home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / examples / demo / demosrc / d_optimize.pro < prev    next >
Text File  |  1997-07-08  |  91KB  |  2,962 lines

  1. ; $Id: d_optimize.pro,v 1.17 1997/04/21 19:52:51 tremblay Exp $
  2. ;
  3. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5. ;
  6. ;+
  7. ;  FILE:
  8. ;       d_optimize.pro
  9. ;
  10. ;  CALLING SEQUENCE: d_optimize
  11. ;
  12. ;  PURPOSE:
  13. ;       Shows the path taken by 2 optimization algorithms :
  14. ;       Powell and DFP.
  15. ;  MAJOR TOPICS: Data analysis and plotting
  16. ;
  17. ;  CATEGORY:
  18. ;       IDL 5.0
  19. ;
  20. ;  INTERNAL FUNCTIONS and PROCEDURES:
  21. ;       pro opt_init16Colors    - Initialize 16 working colors
  22. ;       pro opt_initPoint       - Initialize the starting points coordinates
  23. ;       pro opt_resetPoint      - Redraw the starting point
  24. ;       pro opt_resetSurface    - Redraw the surface (function)
  25. ;       pro opt_resetResults    - Reset the result labels
  26. ;       pro opt_showStart       - Show the starting point (Label and point)
  27. ;       pro about_Optimization  - Display the inforation file
  28. ;       pro opt_plotPoint       - Plot the points along the path
  29. ;       pro DFP                 - DFP algorithm
  30. ;       pro poweop              - Powell algorithm
  31. ;       pro optimize_Event      - Event handler
  32. ;       pro optimize_Cleanup    - Cleanup
  33. ;       pro d_optimize            - Main procedure
  34. ;
  35. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  36. ;       pro funcop              - function to minimize (DFP and Powell)
  37. ;       pro linmop              - subroutine in Powell
  38. ;       pro breop5              - subroutine in Powell
  39. ;       pro mnbop5              - subroutine in Powell
  40. ;       pro f1dop5              - subroutine in Powell
  41. ;       pro sign                - subroutine in Powell
  42. ;       fun gettips             - Get the tip text structure.
  43. ;       pro widtips             - Create the widget text for tips.
  44. ;       pro widtips             - Size the widget text for tips.
  45. ;       optimize.txt
  46. ;       optimize.tip
  47. ;
  48. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  49. ;             Numerical recipes in C, 2nd ed. 
  50. ;             Press, Vetterling, Teukolsky, and Flannery
  51. ;             Cambridge University Press
  52. ;             ISBN 0-521-43108-5
  53. ;
  54. ;  NAMED STRUCTURES:
  55. ;       none.
  56. ;
  57. ;  COMMON BLOCS:
  58. ;       none.
  59. ;
  60. ;  MODIFICATION HISTORY:  Written by: DAT,RSI, 1996
  61. ;
  62. ;-
  63.  
  64. ; $Id: d_optimize.pro,v 1.17 1997/04/21 19:52:51 tremblay Exp $
  65. ;
  66. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  67. ;       Unauthorized reproduction prohibited.
  68. ;
  69. ;+
  70. ;  FILE:
  71. ;       dfp.pro
  72. ;
  73. ;  CALLING SEQUENCE: dfp
  74. ;
  75. ;  PURPOSE:  Compute the minimum of a given function
  76. ;            using the Dorovan-Fletcher-Powell (DFP) algorithm.
  77. ;            Specific use for optim5.pro
  78. ;
  79. ;  MAJOR TOPICS: Data analysis
  80. ;
  81. ;  CATEGORY:
  82. ;       IDL 4.0
  83. ;
  84. ;  INTERNAL FUNCTIONS and PROCEDURES:
  85. ;       fun grad                - Returns the gradient
  86. ;       pro lnsrch              - Perform the line search
  87. ;       pro dfp                 - Main procedure
  88. ;
  89. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  90. ;       pro funcop              - Returns the funciton value
  91. ;
  92. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  93. ;             Numerical recipes in C, 2nd ed.
  94. ;             Press, Vetterling, Teukolsky, and Flannery
  95. ;             Cambridge University Press
  96. ;             ISBN 0-521-43108-5
  97. ;
  98. ;  NAMED STRUCTURES:
  99. ;       none.
  100. ;
  101. ;  COMMON BLOCS:
  102. ;       none.
  103. ;
  104. ;  MODIFICATION HISTORY:Written by DAT,RSI, June 1996
  105. ;-
  106. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  107. ;       Unauthorized reproduction prohibited.
  108. ;
  109. ;+
  110. ;  FILE:
  111. ;       funcop.pro
  112. ;
  113. ;  CALLING SEQUENCE: funcop
  114. ;                    Called by : dfp.pro
  115. ;                                f1dop5.pro
  116. ;                                lnarch.pro
  117. ;                                poweop.pro
  118. ;
  119. ;  PURPOSE:  Returns the function value.
  120. ;            Specific use for optim5.pro
  121. ;
  122. ;  MAJOR TOPICS: Data analysis
  123. ;
  124. ;  CATEGORY:
  125. ;       IDL 4.0
  126. ;
  127. ;  INTERNAL FUNCTIONS and PROCEDURES:
  128. ;       NONE
  129. ;
  130. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  131. ;       NONE
  132. ;
  133. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  134. ;             Numerical recipes in C, 2nd ed.
  135. ;             Press, Vetterling, Teukolsky, and Flannery
  136. ;             Cambridge University Press
  137. ;             ISBN 0-521-43108-5
  138. ;
  139. ;  NAMED STRUCTURES:
  140. ;       none.
  141. ;
  142. ;  COMMON BLOCS:
  143. ;       none.
  144. ;
  145. ;  MODIFICATION HISTORY:Written by DAT,RSI, June 1996
  146. ;-
  147. ;---------------------------------------------------------------------------
  148. ;
  149. ;  Purpose:  Returns the funciton value at point X
  150. ;
  151. function FUNCOP, $
  152.     X, $           ; IN: data coordinates
  153.     surfaceIndex   ; IN: surface index (1, 2, or 3)
  154.  
  155.     x(0) = double(x(0))
  156.     x(1) = double(x(1))
  157.  
  158.     ;  Banana function.
  159.     ;
  160.     if (surfaceIndex EQ 1 ) then begin
  161.         val = 100.0D0*(x(1)-x(0)*x(0))^2 + (1.0-x(0))^2
  162.         RETURN, DOUBLE(val)
  163.     endif
  164.  
  165.     if (surfaceIndex EQ 2 ) then begin
  166.         RETURN, 3.0 * (1.0-x(0))^2 * EXP(-x(0)^2 - (x(1)+1.0)^2)            $
  167.             -10.0 * (x(0)/5.0 - x(0)^3 - x(1)^5) * EXP(-x(0)^2 - x(1)^2) $
  168.             -EXP(-(x(0)+1.0)^2 - x(1)^2)/3.0
  169.     endif
  170.  
  171.     if (surfaceIndex EQ 3 ) then begin
  172.         RETURN, DOUBLE( (x(0) + 2.0 *x(1) ) * exp(-x(0)^2 - x(1)^2) ) 
  173.     endif
  174.  
  175. end  ; Of FUNCOP
  176.  
  177.  
  178. ;---------------------------------------------------------------------------
  179. ;
  180. ;  Purpose: Returns the gradient value at point X
  181. ;
  182. function GRAD, $
  183.     X, $          ; IN: data point
  184.     surfaceindex  ; IN: surface index (1, 2, or 3).
  185.  
  186.     x(0) = double(x(0))
  187.     x(1) = double(x(1))
  188.  
  189.     ;  Function # 1  : banana function.
  190.     ;
  191.     if (surfaceindex eq 1) then begin
  192.          dzdx0= -400.0*x(0)*(x(1)-x(0)*x(0)) - 2*(1-x(0))
  193.          dzdx1= 200.0*(x(1)-x(0)*x(0))
  194.          RETURN, [double(dzdx0),double(dzdx1)]
  195.     endif
  196.  
  197.     ;  Function # 2 .
  198.     ;
  199.     if (surfaceindex eq 2) then begin
  200.         exp0 = exp(-x(0)^2 -(x(1)+1.0)^2)
  201.         exp1 = exp(-x(0)^2 -x(1)^2)
  202.         exp2 = exp(-(x(0)+1.0)^2 -x(1)^2)
  203.         xy   = x(0)/5.0 - x(0)^3 - x(1)^5
  204.         RETURN, DOUBLE( [-6.0*exp0*( x(0) * (1.0-x(0))^2 + (1.0-x(0)) ) $
  205.            -10.0 * exp1 * (-2.0 * x(0) * xy + (0.2 - 3.0 * x(0)^2))  $
  206.            +2.0 * (x(0) + 1.0) * exp2/3.0,                           $
  207.            -6.0 * (x(1) + 1.0) * (1.0 - x(0))^2 * exp0               $
  208.            -10.0 * exp1 * (-2.0 * x(1) * xy - (5.0 * x(1)^4))        $
  209.             +2.0 * x(1) * exp2/3.0] )
  210.     endif
  211.  
  212.     ;  Function # 3 .
  213.     ;
  214.     if (surfaceindex eq 3) then begin
  215.         exp0 = DOUBLE( exp(-x(0)^2 - x(1)^2) )
  216.         RETURN, DOUBLE([exp0 * (1.0 - 2.0*x(0)*x(0) - 4.0*x(0)*x(1) ),  $  
  217.             exp0 * (2.0 - 4.0*x(1)*x(1) - 2.0*x(0)*x(1) ) ] )
  218.     endif
  219.  
  220. end                   ; Of GRAD
  221.  
  222. ;---------------------------------------------------------------------------
  223. ;
  224. ;  Purpose: Execure the line search.
  225. ;
  226. pro LNSRCH, $
  227.     n, $                         ; IN: Dimension of the function
  228.     xold, $                      ; IN: Old point coordinates
  229.     fold, $                      ; IN: Old function value at x old
  230.     g, $                         ; IN/OUT: Vector of lenght n+1, 
  231.                                  ;         where g(0) is the step limit,  
  232.                                  ;         9(1) to g(n) is the returned
  233.                                  ;         gradient at point x
  234.     p,  $                        ; OUT: Newton direction (dim = n+1)
  235.     x, $                         ; OUT: New x  coordinates (dim = n+1),
  236.                                  ;      x(0) contains the check flag.
  237.     f, $                         ; OUT: Function value at point x
  238.     Surfaceindex = surfaceindex  ; IN ; function index
  239.  
  240.     ;  Make variable as double types.
  241.     ;
  242.     xold = double(xold)
  243.     fold = double(fold)
  244.     g = double(g)
  245.  
  246.     ;  Initialize constants.
  247.     ; 
  248.     stpmax = g(0)   ; Maximum number of steps
  249.     check = x(0)    ; check flag is false (0) on normal exit
  250.     tolx = 1.0D-7   ; convergence criterion on DELTA x
  251.     alf = 1.0D-4    ; Ensures sufficient decrease in function x
  252.  
  253.     ;  Check for proper dimension on x.
  254.     ;
  255.     sizen = SIZE(xold)
  256.     ns = sizen(1)
  257.     if (ns NE (n+1)) then begin
  258.         Message,'Error in LNSRCH, dimension of xold  NE n'
  259.     ENDIF
  260.  
  261.     check = 0.0D0
  262.     x(0) = check
  263.     p(0) = 0.0D0
  264.     sum = 0.0D0
  265.     sum = TOTAL(DOUBLE(p(1:n)*p(1:n)) )
  266.     sum = SQRT(sum)
  267.  
  268.     ;  Scale in attempted step is too big.
  269.     ;
  270.     if (sum GT stpmax) then begin
  271.         p(1:n) = DOUBLE(p(1:n)) * DOUBLE( stpmax)/sum
  272.     endif
  273.  
  274.     slope = 0.0D0
  275.     slope = TOTAL(double( g(1:n)*p(1:n) ))
  276.     test = 0.0D0
  277.  
  278.     for i = 1,n do begin
  279.         temp = ABS(p(i)) / MAX( [ABS(xold(i)), 1.0D0] )
  280.         if (temp GT test) THEN test = temp
  281.     endfor
  282.  
  283.     alamin = DOUBLE( tolx/test )
  284.     alam = 1.0D0
  285.     alam2 =0.0D0
  286.     fold2 =0.0D0
  287.     f2 = 0.0D0
  288.     count =0
  289.     dummy = 50
  290.  
  291.     ;  Start of iteration loop.
  292.     ;
  293.     while (dummy EQ 50 ) do begin
  294.         count = count + 1
  295.         x(1:n) = DOUBLE( xold(1:n) + alam*p(1:n) )
  296.         f = DOUBLE(FUNCOP(x(1:n),surfaceindex))
  297.  
  298.         if (alam LT alamin) then begin  ; if 1
  299.             x(1:n) = DOUBLE( xold(1:n) )
  300.             check = 1.0D0
  301.             x(0) = 1.0D0
  302.             RETURN
  303.         endif else if (f LE (fold+alf*alam*slope)) then begin ; if 1
  304.             RETURN
  305.         endif else begin     ; if 1 still
  306.             if ((alam EQ 1.0D0) ) then begin ; if 2
  307.                 tmplam = (-1.0D0*slope)/(2.0D0*(f-fold-slope))
  308.             endif else begin ; if 2
  309.                 rhs1 = DOUBLE( f -fold-alam*slope )
  310.                 rhs2 = DOUBLE( f2-fold2-alam2*slope )
  311.                 alamp2 = DOUBLE( alam*alam )
  312.                 alam2p2 = DOUBLE( alam2 * alam2 )
  313.                 alamdi = DOUBLE( alam-alam2 )
  314.                 a = DOUBLE( ((rhs1/alamp2)-(rhs2/alam2p2))/alamdi )
  315.                 b = DOUBLE( ( (-1.0D0*alam2*rhs1/alamp2) + $
  316.                     (alam*rhs2/alam2p2))/alamdi )
  317.  
  318.                 if (a EQ 0.0D0) then begin ; if 3
  319.                     tmplam =  -1.0D0*slope/(2.0D0*b)
  320.                 endif else begin ; if 3
  321.                     disc = b*b-3.0D0*a*slope
  322.  
  323.                     if (disc LT 0.0D0) then begin ; if 4
  324.                         Message, ' Roundoff problem in lnsrch'
  325.                     endif else begin
  326.                         tmplam = (-1.0D0*b + sqrt(disc))/(3.0D0*a)
  327.                     endelse   ; end of if loop 4
  328.                 endelse   ; end of if loop 3
  329.  
  330.                 if (tmplam GT 0.5D0*alam) THEN tmplam = 0.5D0*alam
  331.             endelse   ; end of if loop 2
  332.         endelse   ; end of if loop 1
  333.  
  334.         alam2 = DOUBLE(alam)
  335.         f2 = DOUBLE( f )
  336.         fold2 = DOUBLE( fold )
  337.         alam = MAX( [tmplam, 0.1D0*alam])
  338.     endwhile
  339.  
  340. end       ; of lnsrch procedure
  341.  
  342. ;---------------------------------------------------------------------------
  343. ;
  344. ;  Purpose:  This function computes the minimum point of a function
  345. ;            using the Dorovan-fletcher-Powell algorithm.
  346. ;            The IDL equivalent is called DFPMIN. The difference is
  347. ;            that DFP returns the intermediary steps.
  348. ;            For details and comments see Numerical recipes in C 2nd ed.
  349. ;
  350. pro dfp, $
  351.     n, $                         ; IN: Dimension of the function
  352.     p, $                         : IN: Vector (n+1) containing the initial 
  353.     gtol, $                      : IN: Limit of tolerance
  354.     iter, $                      : OUT: Number of iterations
  355.     xtot, $                      : OUT: Array ( iter+1, n+1) 
  356.                                  ;      that contains the data path.
  357.     Surfaceindex                 ; IN ; function index
  358.    
  359.     ;  Initialize constants.
  360.     ;
  361.     itmax = 200               ; maximum number of iterations
  362.     eps = 3.0D-7              ; machine precision
  363.     tolx = double(4.0* eps)   ; Convergence criterion on x
  364.     stpmx = double(100.0)     ; scaled max. step length allowed in LNSRCH
  365.  
  366.     ;  Initialize working arrays.
  367.     ;
  368.     dg = DBLARR(n+1)
  369.     g = DBLARR(n+1)
  370.     pnew = DBLARR(n+1)
  371.     hdg = DBLARR(n+1)
  372.     hessin = DBLARR(n+1,n+1)
  373.     xi = DBLARR(n+1)
  374.  
  375.     ;  Evaluate the function value at the starting point.
  376.     ;
  377.     fp = FUNCOP(double(p(1:n)), surfaceindex)
  378.  
  379.     ;  Evaluate the function gradient at the starting point.
  380.     ;  
  381.     g(1:n) = GRAD(DOUBLE(p(1:n)), surfaceindex)
  382.  
  383.     xtot(0,0:1) =DOUBLE( p(1:2) )
  384.     xtot(0,2) = DOUBLE(fp)
  385.  
  386.     ; Initialize the matrix hessin to the identity matrix
  387.     ;
  388.     hessin = hessin + DOUBLE(0.0)
  389.     for i = 1, n do begin
  390.         hessin(i,i) = DOUBLE(1.0)
  391.     endfor
  392.  
  393.     sum = TOTAL(DOUBLE( p(1:n)*p(1:n) ) )
  394.     xi(1:n) =  DOUBLE( -g(1:n) )
  395.     stpmax = stpmx*MAX([DOUBLE(n),SQRT(sum)])
  396.  
  397.     ; Begin loop over max number of iterations
  398.     ;
  399.     for its=1, itmax do begin
  400.         g(0) = DOUBLE(stpmax)
  401.         xi(0) = DOUBLE(0.0)
  402.         iter = its
  403.  
  404.         ;  Performs a line search by calling the function LNSRCH.
  405.         ;
  406.         LNSRCH,n,p,fp,g,xi,pnew,fret, Surfaceindex = surfaceindex
  407.    
  408.         xtot(its,0:1) = DOUBLE( pnew(1:2) )
  409.         xtot(its,2) = DOUBLE(fret )
  410.         check = DOUBLE( pnew(0) )
  411.         fp = DOUBLE(fret)
  412.         xi(1:n) = DOUBLE( pnew(1:n) - p(1:n) )
  413.         p(1:n) = pnew(1:n)
  414.         test = DOUBLE(0.0)
  415.         
  416.         for i = 1, n do begin
  417.            temp = DOUBLE(ABS(xi(i)) / MAX( [ABS(p(i)),double(1.0)]))
  418.            if (temp GT test) then test = temp
  419.         endfor
  420.    
  421.         if (test LT tolx) then RETURN
  422.  
  423.         dg(1:n) = DOUBLE( g(1:n) )
  424.    
  425.         ;  Get the dradient at the new point.
  426.         ;
  427.         g(1:n) = GRAD(DOUBLE( p(1:n)),surfaceindex)
  428.    
  429.         test = DOUBLE(0.0)
  430.         den = MAX([DOUBLE(fret),1.0D0])
  431.  
  432.         for i = 1, n do begin
  433.            temp = ABS(g(i))*MAX([ABS(p(i)),1.0D0])/den
  434.            IF(temp GT test) THEN test = temp
  435.         endfor
  436.  
  437.         ;  Return if test is smaller that the tolerance limit.
  438.         ;
  439.         if (test LT gtol) then RETURN
  440.  
  441.         dg(1:n) = double(  g(1:n) - dg(1:n) )
  442.         hdg(1:n) = double( dg(1:n) - dg(1:n) )
  443.         hdg(1:n) = double( dg(1:n) ## hessin(1:n,1:n) )
  444.  
  445.         ;  Initialize working variables.
  446.         ;
  447.         fac   = 0.0D0
  448.         fae   = 0.0D0
  449.         sumdg = 0.0D0
  450.         sumxi = 0.0D0
  451.  
  452.         fac   = TOTAL( DOUBLE( dg(1:n) *xi(1:n) ))
  453.         fae   = TOTAL(DOUBLE( dg(1:n) * hdg(1:n) ))
  454.         sumdg = TOTAL( DOUBLE( dg(1:n)*dg(1:n) ))
  455.         sumxi = TOTAL(DOUBLE( xi(1:n)*xi(1:n) ))
  456.  
  457.         if ((fac * fac) GT (eps*sumdg*sumxi) ) then begin
  458.            fac = 1.0D0/fac
  459.            fad = 1.0D0/fae
  460.            dg(1:n) = fac*xi(1:n) - fad*hdg(1:n)
  461.            hessin(1:n,1:n) = hessin(1:n,1:n) + $
  462.            transpose(fac*xi(1:n)##xi(1:n) - $
  463.            fad*hdg(1:n)##hdg(1:n) +fae*dg(1:n)##dg(1:n) )
  464.         endif
  465.  
  466.         xi = double( xi-xi )
  467.         hessint = double( -1.0D0*hessin )
  468.         xi(1:n) = double( g(1:n) ## hessint(1:n,1:n) )
  469.  
  470.     ;  End of iteration loop.
  471.     ;
  472.     endfor
  473.  
  474.     ; If the function does not returns from inside the
  475.     ; previous loop, then returns the message
  476.     ; 
  477.     MESSAGE, ' Too many iterations in DFPMIN'
  478.  
  479. end                  ; Of DFP function
  480.  
  481. ;
  482. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  483. ;       Unauthorized reproduction prohibited.
  484. ;
  485. ;+
  486. ;  FILE:
  487. ;       poweop.pro
  488. ;
  489. ;  CALLING SEQUENCE: poweop
  490. ;                    Called by : linmop.pro
  491. ;
  492. ;  PURPOSE:  Computes the minimum (optimization) of a function
  493. ;            using the POWELL algorthm.
  494. ;            Specific use for optim5.pro
  495. ;
  496. ;  MAJOR TOPICS: Data analysis
  497. ;
  498. ;  CATEGORY:
  499. ;       IDL 4.0
  500. ;
  501. ;  INTERNAL FUNCTIONS and PROCEDURES:
  502. ;       NONE.
  503. ;
  504. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  505. ;       pro funcop              - Returns the function value
  506. ;       pro linmop              - returns minimum along a direction.
  507. ;
  508. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  509. ;             Numerical recipes in C, 2nd ed.
  510. ;             Press, Vetterling, Teukolsky, and Flannery
  511. ;             Cambridge University Press
  512. ;             ISBN 0-521-43108-5
  513. ;
  514. ;  NAMED STRUCTURES:
  515. ;       NONE.
  516. ;
  517. ;  COMMON BLOCS:
  518. ;       NONE.
  519. ;
  520. ;  MODIFICATION HISTORY: Written by DAT,RSI, June 1996
  521. ;-
  522. ;---------------------------------------------------------------------------
  523. ;
  524. ;  Purpose: Compute the minimum of a function
  525. ;           using hte POWELL algortihm.
  526. ;
  527. pro POWEOP, $
  528.     p, $                     ; IN/OUT: initial starting point
  529.     xi, $                    ; IN: initial matrix (usually identity matrix)
  530.     ftol, $                  ; IN: fractional tolerance
  531.     iter, $                  ; OUT: number of iterations
  532.     fret, $                  ; OUT; function value at minimum point (fret)
  533.     path, $                  ; OUT: array containing the iteration steps.
  534.     status, $                : OUT: function status (0=failure, 1=success)
  535.     SURFACEINDEX=surfaceindex; IN: Surface index (1, 2,or 3)
  536.  
  537.     ;  Get the dimension of the function.
  538.     ;
  539.     n = p(0)
  540.     n = 2
  541.  
  542.     ;  Initialize working variables and arrays.
  543.     ;
  544.     ITMAX    = 200                  ; maximuim number of iterations allowed
  545.     NMAX     = 21                   ; maximum dimension of the system.
  546.     i        = 0                    ; integer
  547.     ibig     = 0                    ; integer
  548.     j        = 0                    ; integer
  549.     del      = 0.0D0                ; DOUBLE precision
  550.     fp       = 0.0D0                ; DOUBLE precision
  551.     fptt     = 0.0D0                ; DOUBLE precision
  552.     t        = 0.0D0                ; DOUBLE precision
  553.     pt       = DBLARR(nmax)         ; array
  554.     ptt      = DBLARR(nmax)         ; array
  555.     xit      = DBLARR(nmax)         ; array
  556.     status   = 1                    ; Status is Valid (OK)
  557.     iter     = 1                    ; iteration number
  558.     path     = DBLARR(itmax+1, n+1) ; array
  559.  
  560.  
  561.     ;  Get the function value at point p.
  562.     ;
  563.     fret = DOUBLE(FUNCOP(p(1:n), surfaceIndex) )
  564.  
  565.     ;  Initialize the vector path.
  566.     ;
  567.     path(0, 0:n-1 ) = p(1:n)
  568.     path(0, n) = fret
  569.  
  570.     ;  Set pt to p. Save the initial point.
  571.     ;
  572.     pt(1:n) = DOUBLE( p(1:n) )
  573.  
  574.     ;  Loop over iteration.
  575.     ;  Integer iter has already been set to one. It is
  576.     ;  incremented at the end of the for loop.
  577.     ;
  578.     dummy = 0
  579.  
  580.     for iter = 1, ITMAX+1 do begin
  581.  
  582.         fp = DOUBLE( fret )
  583.         ibig = 0
  584.         del = 0.0D0       ; Will be the biggest function decrease
  585.  
  586.         ;  In each iteration, loop over all directions in the set.
  587.         ;
  588.         for i = 1, n  do begin
  589.  
  590.             ;  Copy the direction.
  591.             ; 
  592.             xit(1:n) = DOUBLE( xi( 1:n, i)  )
  593.             fptt = DOUBLE(  fret )
  594.  
  595.             ;  Minimize along that direction.
  596.             ;
  597.             linmop, p, xit, n, fret, check, $
  598.                 SURFACEINDEX=surfaceIndex
  599.   
  600.             ;  Verify the check status of linmin.
  601.             ;
  602.             if (check EQ 0) then begin
  603.                 PRINT, ' Error in linmop NO 1 in POWEOP.pro'
  604.                 RETURN
  605.             endif
  606.  
  607.             ;  Augment the vector path.
  608.             ;
  609.             path(iter, 0:n-1) =DOUBLE( p(1:n) )
  610.             path(iter, n) = DOUBLE( fret )
  611.  
  612.             ;  Record it and if it is the largest decrease so far.
  613.             ;
  614.             if (ABS(fptt - fret) GT del ) then begin
  615.                 del = DOUBLE( ABS( fptt - fret) )
  616.                 ibig = i
  617.             endif
  618.  
  619.         endfor
  620.  
  621.         ;  Termination criterion.
  622.         ;
  623.         if ((2.0* (ABS(fp - fret)) ) LE $
  624.             (ftol*(ABS(fp) + ABS(fret)) ) ) then begin
  625.             status = 1  ; Valid
  626.             RETURN
  627.         endif
  628.  
  629.         if (iter  EQ ITMAX) then begin
  630.             status = 0   ; NOT Valid
  631.             PRINT, 'Number of iteration exceeds the limit in POWELM'
  632.             RETURN
  633.         endif
  634.  
  635.         ;  Construct the extrapolated point and the average
  636.         ;  direction moved. Save the old starting point.
  637.         ;
  638.         ptt(1:n) = DOUBLE( 2.0 * p(1:n) - pt(1:n) )
  639.         xit(1:n) = DOUBLE( p(1:n) - pt(1:n) )
  640.         pt(1:n) = DOUBLE( p(1:n) )
  641.  
  642.         ;  Function value at extrapolated point.
  643.         ;
  644.         fptt = DOUBLE( FUNCOP( ptt(1:n), surfaceIndex) )
  645.  
  646.  
  647.         ;  Move to the minimum of the new direction,
  648.         ;  and save the new direction.
  649.         ;
  650.         if (fptt LT fp) then begin
  651.             square1 = DOUBLE(  (fp - fret - del) * (fp - fret - del) )
  652.             square2 = DOUBLE( (fp - fptt) * (fp - fptt) )
  653.             t = DOUBLE( 2.0*(fp - (2.0*fret) + fptt) * square1 - $ 
  654.                 del * square2 )
  655.             if (t LT 0.0d) then begin
  656.                 linmop, p, xit, n, fret, check, $
  657.                     SURFACEINDEX=surfaceIndex
  658.  
  659.                 ;  Verify the check status of linmin.
  660.                 ;
  661.                 if (check EQ 0) then begin
  662.                     PRINT, ' Error in linmop NO 2 in POWEOP.pro'
  663.                     RETURN
  664.                 endif
  665.  
  666.                 ;  Augment or reset  the vector path.
  667.                 ;
  668.                 path(iter, 0:n-1) = p(1:n)
  669.                 path(iter, n) = DOUBLE( fret )
  670.                 xi(1:n, ibig) = DOUBLE( xi( 1:n, n) )
  671.                 xi(1:n, n)    = DOUBLE( xit(1:n) )
  672.             endif
  673.         endif
  674.     endfor
  675.  
  676. end   ; of POWELM.pro
  677.  
  678.  
  679. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  680. ;       Unauthorized reproduction prohibited.
  681. ;
  682. ;+
  683. ;  FILE:
  684. ;       sign.pro
  685. ;
  686. ;  CALLING SEQUENCE: sign
  687. ;                    Called by : linmop.pro
  688. ;                                breop5.pro
  689. ;
  690. ;  PURPOSE:  This function isolates the minimum to a fractional
  691. ;            precision of about tol using Brent's method.
  692. ;            Specific use for optim5.pro
  693. ;
  694. ;  MAJOR TOPICS: Data analysis
  695. ;
  696. ;  CATEGORY:
  697. ;       IDL 4.0
  698. ;
  699. ;  INTERNAL FUNCTIONS and PROCEDURES:
  700. ;        pro sign               - main procedure
  701. ;
  702. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  703. ;      NONE
  704. ;
  705. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  706. ;             Numerical recipes in C, 2nd ed.
  707. ;             Press, Vetterling, Teukolsky, and Flannery
  708. ;             Cambridge University Press
  709. ;             ISBN 0-521-43108-5
  710. ;
  711. ;  NAMED STRUCTURES:
  712. ;       none.
  713. ;
  714. ;  COMMON BLOCS:
  715. ;       none.
  716. ;
  717. ;  MODIFICATION HISTORY:Written by DAT,RSI, June 1996
  718. ;-
  719. ;---------------------------------------------------------------------------
  720. ;
  721. ;  Purpose:  This function returns  
  722. ;            absolute of arg1         if arg2 is positive
  723. ;            minus  absolute of arg1  if arg2 is less or equal to 0
  724. ;
  725. function SIGN, $
  726.     arg1, $       ; IN: argument 1
  727.     arg2, $       ; IN: argument2
  728.     STATUS=status ; OUT: 0 = failure, 1= success
  729.  
  730.     if (N_Elements(status) ) then begin
  731.         status = 1
  732.     endif
  733.  
  734.     nparam = N_Params()
  735.     if (nparam NE 2) THEN BEGIN
  736.         print, ' Error calling SIGN, must have 2 arguments'
  737.         status = 0
  738.         RETURN, double( arg1)
  739.     endif
  740.  
  741.     if (arg2 GT 0.0) then begin 
  742.         RETURN, double( ABS(arg1) )
  743.     endif else begin
  744.         RETURN, double( -(ABS(arg1))  )
  745.     endelse
  746.  
  747. end   ; of function SIGN
  748.  
  749.  
  750.  
  751. ;
  752. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  753. ;       Unauthorized reproduction prohibited.
  754. ;
  755. ;+
  756. ;  FILE:
  757. ;       f1dop5.pro
  758. ;
  759. ;  CALLING SEQUENCE: f1dop5
  760. ;                    Called by : breop5.pro
  761. ;
  762. ;  PURPOSE:  Returns the function value at the updated point.
  763. ;            Specific use for optim5.pro
  764. ;
  765. ;  MAJOR TOPICS: Data analysis
  766. ;
  767. ;  CATEGORY:
  768. ;       IDL 4.0
  769. ;
  770. ;  INTERNAL FUNCTIONS and PROCEDURES:
  771. ;       pro f1dop5              - Main procedure
  772. ;
  773. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  774. ;       pro funcop              - Returns the function value
  775. ;
  776. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  777. ;             Numerical recipes in C, 2nd ed.
  778. ;             Press, Vetterling, Teukolsky, and Flannery
  779. ;             Cambridge University Press
  780. ;             ISBN 0-521-43108-5
  781. ;
  782. ;  NAMED STRUCTURES:
  783. ;       none.
  784. ;
  785. ;  COMMON BLOCS:
  786. ;       none.
  787. ;
  788. ;  MODIFICATION HISTORY:Written by DAT,RSI, June 1996
  789. ;-
  790. ;---------------------------------------------------------------------------
  791. ;
  792. ;  Purpose: Returns the function value at the updated point.
  793. ;
  794. function f1dop5, $
  795.     x , $                       ; IN: non updated point 
  796.     pcom, $                     ; IN: vector for updaing the point
  797.     xicom, $                    ; IN: vector for updaing the point
  798.     ncom, $                     ; IN: dimension of the function
  799.     status, $                   ; OUT: status check flag.
  800.     SURFACEINDEX=surfaceindex   ; IN: surface index
  801.  
  802.     ;  Check the validity of input parameters.
  803.     ;
  804.     nparam = N_Params()
  805.     if (nparam NE 5) then begin
  806.         PRINT, ' Error calling f1dim, must have 5 arguments'
  807.         status = 0
  808.         RETURN, x
  809.     endif
  810.  
  811.     ;  Set status to valid.
  812.     ;
  813.     status = 1
  814.  
  815.     ;  Initialize variables.
  816.     ;
  817.     f  =  0.0D0            ; double precision
  818.     xt =  dblarr(ncom+1)   ; double precision
  819.  
  820.     ;  Update the point.
  821.     ;
  822.     xt(1:ncom) = double( pcom(1:ncom) + x*xicom(1:ncom) )
  823.  
  824.     ;  Get the function value at point  xt.
  825.     ;
  826.     f = double( FUNCOP( xt(1:ncom),surfaceindex ) )
  827.  
  828.     RETURN, f
  829.  
  830. end   ; of f1dim.pro
  831.  
  832.  
  833.  
  834. ;
  835. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  836. ;       Unauthorized reproduction prohibited.
  837. ;
  838. ;+
  839. ;  FILE:
  840. ;       breop5.pro
  841. ;
  842. ;  CALLING SEQUENCE: breop5
  843. ;                    Called by : linmop.pro
  844. ;
  845. ;  PURPOSE:  This function isolates the minimum to a fractional
  846. ;            precision of about tol using Brent's method.
  847. ;            Specific use for optim5.pro
  848. ;
  849. ;  MAJOR TOPICS: Data analysis
  850. ;
  851. ;  CATEGORY:
  852. ;       IDL 4.0
  853. ;
  854. ;  INTERNAL FUNCTIONS and PROCEDURES:
  855. ;       fun f1dop5              - Compute line vlaue.
  856. ;       pro sign                - Return the sign.
  857. ;       pro breop5              - Main procedure
  858. ;
  859. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  860. ;       pro funcop              - Returns the function value
  861. ;
  862. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  863. ;             Numerical recipes in C, 2nd ed.
  864. ;             Press, Vetterling, Teukolsky, and Flannery
  865. ;             Cambridge University Press
  866. ;             ISBN 0-521-43108-5
  867. ;
  868. ;  NAMED STRUCTURES:
  869. ;       none.
  870. ;
  871. ;  COMMON BLOCS:
  872. ;       none.
  873. ;
  874. ;  MODIFICATION HISTORY:Written by DAT,RSI, June 1996
  875. ;-
  876. ;---------------------------------------------------------------------------
  877. ;
  878. ;  Purpose: Isolate the minimum value.
  879. ;
  880. function BREOP5, $
  881.     ax, $                       ; IN: Inital abscissa
  882.     bx, $                       ; IN: Inital abscissa
  883.     cx, $                       ; IN: Inital abscissa
  884.     tol, $                      ; IN: Limit of tolerance
  885.     xmin, $                     ; OUT: Returned minimum 
  886.     status ,$                   ; OUT: 0 = Not valid for function BRENT
  887.     Ppassed = pp, $             ; IN: Vector passed to BRENT
  888.     Xipassed = xip, $           ; IN: Vector passed to BRENT
  889.     Npassed = np, $             ; IN: Value  passed to BRENT
  890.     SurfaceIndex=surfaceindex
  891.  
  892.     ;  Verify that p, n, and xi have been passed correctly.
  893.     ;
  894.     keywordp = N_Elements(pp)
  895.     if (keywordp EQ 0 ) then begin
  896.         PRINT, ' Error : p not passed to BRENT'
  897.         status = 0
  898.         RETURN, 0
  899.     endif
  900.  
  901.     keywordn = N_Elements(np)
  902.     if (keywordn EQ 0 ) then begin
  903.         PRINT, ' Error : n not passed to BRENT'
  904.         status = 0
  905.         RETURN, 0
  906.     endif
  907.  
  908.     keywordxi = N_Elements(xip)
  909.     if (keywordxi EQ 0 ) then begin
  910.         PRINT, ' Error : xi not passed to BRENT'
  911.         status = 0
  912.         RETURN, 0
  913.     endif
  914.  
  915.     ;  Initialize working variables and arrays.
  916.     ;
  917.     itmax  = 100           ; maximum number of iterations
  918.     cgold  = 0.381966D0   ; golden ratio 
  919.     zeps   = 1.0D-10       ; small number for numerical protection
  920.     iter   = 0             ; iteration number
  921.     a      = 0.0D0         ; DOUBLE precision
  922.     b      = 0.0D0         ; DOUBLE precision
  923.     d      = 0.0D0         ; DOUBLE precision
  924.     etemp  = 0.0D0         ; DOUBLE precision
  925.     fu     = 0.0D0         ; DOUBLE precision
  926.     fv     = 0.0D0         ; DOUBLE precision
  927.     fw     = 0.0D0         ; DOUBLE precision
  928.     fx     = 0.0D0         ; DOUBLE precision
  929.     p      = 0.0D0         ; DOUBLE precision
  930.     q      = 0.0D0         ; DOUBLE precision
  931.     r      = 0.0D0         ; DOUBLE precision
  932.     tol1   = 0.0D0         ; DOUBLE precision
  933.     tol2   = 0.0D0         ; DOUBLE precision
  934.     u      = 0.0D0         ; DOUBLE precision
  935.     v      = 0.0D0         ; DOUBLE precision
  936.     w      = 0.0D0         ; DOUBLE precision
  937.     x      = 0.0D0         ; DOUBLE precision
  938.     xm     = 0.0D0         ; DOUBLE precision
  939.     e      = 0.0D0         ; Distance moved on the step before last
  940.     status = 1             ; Status is Valid (OK)
  941.  
  942.     if (ax LT cx) then a = ax else a = cx
  943.     if (ax GT cx) then b = ax else b = cx
  944.  
  945.     x = DOUBLE(bx)
  946.     w = DOUBLE(bx)
  947.     v = DOUBLE(bx)
  948.  
  949.     ;  Call the function f1dim.pro  .
  950.     ;
  951.     fx =DOUBLE( f1dop5(x, pp, xip, np , $
  952.         checkF1dim, SURFACEINDEX=surfaceindex) )
  953.  
  954.     ;  Verify the check status of f1dop5.
  955.     ;
  956.     if (checkF1dim EQ 0) then begin
  957.         PRINT, ' error in F1dim function NO 1 (in BRENT)'
  958.         status = 0
  959.         RETURN, 0
  960.     endif
  961.  
  962.     fv = DOUBLE(fx)
  963.     fw = DOUBLE(fx)
  964.  
  965.     ;  Main loop program.
  966.     ;
  967.     for iter = 1, ITMAX do begin
  968.         xm =  DOUBLE( 0.5*(a + b) )
  969.         tol1 = DOUBLE( tol*ABS(x) + zeps )
  970.         tol2 = DOUBLE( 2.0 * tol1 ) 
  971.    
  972.         ;  Test for done here.
  973.         ;
  974.         if (ABS( x - xm) LE ( tol2 - 0.5d*(b-a)) ) then begin
  975.            xmin = x
  976.            RETURN, fx
  977.         endif
  978.  
  979.         ;  Construct a trial parabolic fit.
  980.         ;
  981.         if (ABS(e) GT tol1 ) then begin
  982.             r = DOUBLE( (x - w) * (fx - fv) )
  983.             q =  DOUBLE( (x - v) * (fx - fw) )
  984.             p =  DOUBLE( (x - v)*q - (x - w)*r )
  985.             q =  DOUBLE( 2.0d * (q - r) )
  986.             if (q GT 0.0d) then p =  DOUBLE( -p )
  987.             q = DOUBLE( ABS(q) )
  988.             etemp = DOUBLE( e )
  989.             e =  DOUBLE( d )
  990.      
  991.             ;  Check for the acceptability for the parabolic fit
  992.             ;  otherwise, take the golden section step into the larger
  993.             ;  of the 2 segments.
  994.             if (( ABS(p) GE ABS(0.5d*q*etemp) ) OR $
  995.                 ( p LE q*(a - x) ) OR $
  996.                 ( p GE q*(b - x) ) ) then begin
  997.  
  998.                 if (x GE xm ) then begin
  999.                     e = DOUBLE(a - x)
  1000.                 endif else begin
  1001.                     e = DOUBLE(b - x)
  1002.                 endelse
  1003.           
  1004.                 d = DOUBLE( cgold * e )
  1005.    
  1006.             endif else begin
  1007.  
  1008.                 d = DOUBLE( p/q )
  1009.                 u = DOUBLE( x + d )
  1010.                 if (( (u-a) LT tol2 ) OR ( (b - u) LT tol2 ) ) then begin
  1011.                     d = DOUBLE( SIGN(tol1, (xm - x), Status = status ) )
  1012.                     if (status EQ 0) then begin
  1013.                         print, ' error in SIGN function NO 1 (in BRENT)'
  1014.                         RETURN, 0
  1015.                     endif
  1016.                 endif
  1017.             endelse
  1018.         endif else begin
  1019.  
  1020.             if (x GE xm ) then begin
  1021.                 e = DOUBLE(a - x)
  1022.             endif else begin
  1023.                 e = DOUBLE(b - x)
  1024.             endelse
  1025.  
  1026.             d = DOUBLE( cgold * e )
  1027.         endelse
  1028.  
  1029.         if (ABS(d) GE tol1) then begin
  1030.             u =  DOUBLE( x+d)
  1031.         endif else begin
  1032.             u = x + SIGN( tol1, d, Status = status)
  1033.             if (status EQ 0) then begin
  1034.                print, ' error in SIGN function NO 2 (in BRENT)'
  1035.                RETURN, 0
  1036.             endif
  1037.         endelse
  1038.    
  1039.         ;  Call the function f1dop5.pro.
  1040.         ;
  1041.         fu = f1dop5(u, pp, xip, np , $
  1042.             checkF1dim, SURFACEINDEX=surfaceindex)
  1043.  
  1044.         ;  Verify the check status of f1dop5.
  1045.         ;
  1046.         if (checkF1dim EQ 0) then begin
  1047.             PRINT, ' error in F1dop5 function NO 2 (in BRENT)'
  1048.             status = 0
  1049.             RETURN, 0
  1050.         endif
  1051.  
  1052.         ;  This is the one function evaluation per iteration.
  1053.         ;
  1054.         if ( fu LE fx) then begin
  1055.             if (u GE x ) then  a = DOUBLE(x)  else b=DOUBLE(x)
  1056.             v = w
  1057.             w = x
  1058.             x = u
  1059.             fv = fw
  1060.             fw = fx
  1061.             fx = fu
  1062.         endif else begin
  1063.  
  1064.             if (u LT x) then a=u else b=u
  1065.  
  1066.             if ((fu LE fw) OR (w EQ x) ) then begin
  1067.                 v  =  DOUBLE(w)
  1068.                 w  = DOUBLE(u)
  1069.                 fv = DOUBLE(fw)
  1070.                 fw = DOUBLE(fu)
  1071.             endif else if ( (fu LE fv) OR (v EQ x) OR (v EQ w) )then begin
  1072.                 v  = DOUBLE(u)
  1073.                 fv = DOUBLE(fu)
  1074.             endif
  1075.         endelse
  1076.  
  1077.     endfor  ; end of the main loop
  1078.  
  1079.     ;  If the program reaches here,
  1080.     ;  then the number of iteration is too high.
  1081.     ;
  1082.     status = 0
  1083.     PRINT, ' Error in BRENT, too many iterations
  1084.     RETURN, 0
  1085.  
  1086. end ; of BRENT
  1087.  
  1088. ;
  1089. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  1090. ;       Unauthorized reproduction prohibited.
  1091. ;
  1092. ;+
  1093. ;  FILE:
  1094. ;       mnbop5.pro
  1095. ;
  1096. ;  CALLING SEQUENCE: mnbop5
  1097. ;                    Called by : linmop.pro
  1098. ;
  1099. ;  PURPOSE:  This function isolates the minimum to a fractional
  1100. ;            precision of about tol using Brent's method.
  1101. ;            Specific use for optim5.pro
  1102. ;
  1103. ;  MAJOR TOPICS: Data analysis
  1104. ;
  1105. ;  CATEGORY:
  1106. ;       IDL 4.0
  1107. ;
  1108. ;  INTERNAL FUNCTIONS and PROCEDURES:
  1109. ;       fun f1dop5              - Compute line value.
  1110. ;       pro sign                - Return the sign.
  1111. ;       pro breop5              - Main procedure
  1112. ;
  1113. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  1114. ;       pro funcop              - Returns the function value
  1115. ;
  1116. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  1117. ;             Numerical recipes in C, 2nd ed.
  1118. ;             Press, Vetterling, Teukolsky, and Flannery
  1119. ;             Cambridge University Press
  1120. ;             ISBN 0-521-43108-5
  1121. ;
  1122. ;  NAMED STRUCTURES:
  1123. ;       none.
  1124. ;
  1125. ;  COMMON BLOCS:
  1126. ;       none.
  1127. ;
  1128. ;  MODIFICATION HISTORY:Written by DAT,RSI, June 1996
  1129. ;-
  1130. ;---------------------------------------------------------------------------
  1131. ;
  1132. ;  Purpose:  This function searches in the downhill direction,  
  1133. ;            and returns the new points ax, bx, cx (as parametrs) that bracket 
  1134. ;            a minimum of the function f1dop5. The status is returned
  1135. ;            as value by the function.
  1136. ;
  1137. function MNBOP5, $
  1138.     ax, $                       ; IN/OUT: initial/final point 
  1139.     bx, $                       ; IN/OUT: initial/final point
  1140.     cx, $                       ; OUT: final point
  1141.     fa, $                       ; OUT: value function at ax
  1142.     fb, $                       ; OUT: value function at bx
  1143.     fc, $                       ; OUT: value function at cx
  1144.     PPASSED = pp, $             ; IN: parameter used by f1dop5
  1145.     XIPASSED = xip, $           ; IN: parameter used by f1dop5
  1146.     NPASSED = np, $             ; IN: parameter used by f1dop5
  1147.     SURFACEINDEX = surfaceIndex ; IN: surface index (1, 2, or 3)
  1148.  
  1149.     ;  Verify that pp, np, and xip have been passed. 
  1150.     ;
  1151.     keywordp = N_ELEMENTS(pp)
  1152.     if (keywordp EQ 0 ) then begin
  1153.         PRINT, ' Error in MNBOP5 : p not passed to MNBOP5'
  1154.         status = 0
  1155.         RETURN, status
  1156.     endif
  1157.  
  1158.     keywordn = N_ELEMENTS(np)
  1159.     if (keywordn EQ 0 ) then begin
  1160.         PRINT, ' Error in MNBOP5 : n not passed to MNBOP5'
  1161.         status = 0
  1162.         RETURN, 0
  1163.     endif
  1164.  
  1165.     keywordxi = N_ELEMENTS(xip)
  1166.     if (keywordxi EQ 0 ) then begin
  1167.         PRINT, ' Error in MNBOP5 : xi not passed to MNBOP5'
  1168.         status = 0
  1169.         RETURN, 0
  1170.     endif
  1171.  
  1172.     ;  Initialize working variables and arrays.
  1173.     ;
  1174.     gold   = 1.618034d     ; default ratio 
  1175.     glimit = 100.0D0       ; max. magnification for parabolic-fit step
  1176.     tiny   = 1.0D-20       ; double precision
  1177.     ulim   = 0.0D0         ; double precision
  1178.     u      = 0.0D0         ; double precision
  1179.     r      = 0.0D0         ; double precision
  1180.     q      = 0.0D0         ; double precision
  1181.     fu     = 0.0D0         ; double precision
  1182.     dum    = 0.0D0         ; double precision
  1183.     status = 1             ; Status is Valid (OK)
  1184.  
  1185.     ;  Call the function f1dop5.pro twice .
  1186.     ;
  1187.     fa = f1dop5(ax, pp, xip, np , checkF1dim, SURFACEINDEX=surfaceindex)
  1188.  
  1189.     ;  Verify the check status of f1dop5.
  1190.     ;
  1191.     if (checkF1dim EQ 0) then begin
  1192.         PRINT, ' error in F1dop5 function NO 1 (in MNBOP5)'
  1193.         status = 0
  1194.         RETURN, 0
  1195.     endif
  1196.  
  1197.     fb = f1dop5(bx, pp, xip, np , checkF1dim, SURFACEINDEX=surfaceindex)
  1198.  
  1199.     ;  Verify the check status of f1dim.
  1200.     ;
  1201.     if (checkF1dim EQ 0) then begin
  1202.         PRINT, ' error in F1dop5 function NO 2 (in MNBOP5)'
  1203.         status = 0
  1204.         RETURN, 0
  1205.     endif
  1206.  
  1207.  
  1208.     ;  Switch roles of a and b so that we can go
  1209.     ;  downhill in the direction for a to b.
  1210.     ;
  1211.     if (fb GT fa) then begin
  1212.         dum = ax
  1213.         ax = bx
  1214.         bx = dum
  1215.         dum = fb
  1216.         fb = fa
  1217.         fa = dum
  1218.     endif
  1219.  
  1220.  
  1221.     ;  First guess for c.
  1222.     ;
  1223.     cx = DOUBLE( bx + gold*(bx - ax) )
  1224.  
  1225.     fc = f1dop5(cx, pp, xip, np , checkF1dim, SURFACEINDEX=surfaceindex)
  1226.  
  1227.     ;  Verify the check status of f1dop5.
  1228.     ;
  1229.     if (checkF1dim EQ 0) then begin
  1230.         PRINT, ' error in F1dim function NO 3 (in MNBOP5)'
  1231.         status = 0
  1232.         RETURN, 0
  1233.     endif
  1234.  
  1235.  
  1236.     ;  Keep returning here until we bracket.
  1237.     ;
  1238.     while (fb GT fc) do begin
  1239.  
  1240.         ;  Compute u by parabolic extrapolation from a,b,c.
  1241.         ;  Tiny is used to prevent any possible division by zero.
  1242.         ;
  1243.         r = DOUBLE( (bx - ax) * (fb - fc) )
  1244.         q = DOUBLE( (bx - cx) * (fb - fa) )
  1245.         valueFmax =  DOUBLE( MAX( ABS(q-r), tiny) )
  1246.         valueSign = SIGN( valueFmax,  (q-r), STATUS=status)
  1247.         if (status eq 0) then begin
  1248.             PRINT, ' Error calling SIGN (in MNBOP5)'
  1249.             RETURN, 0
  1250.         endif
  1251.  
  1252.         u = DOUBLE( bx - ( (bx-cx)*q - (bx-ax)*r ) / $
  1253.             (2.0 * valueSign ) ) 
  1254.  
  1255.         ulim =  DOUBLE( bx + glimit*(cx - bx) )
  1256.    
  1257.         ;  Test various possibility.
  1258.         ;
  1259.         if (((bx - u)*(u - cx)) GT 0.0 )  then begin
  1260.  
  1261.             fu = f1dop5(u, pp, xip, np ,checkF1dim, $
  1262.                 SURFACEINDEX=surfaceindex)
  1263.  
  1264.             ;  Verify the check status of f1dim.
  1265.             ;
  1266.             if (checkF1dim EQ 0) then begin
  1267.                PRINT, ' error in F1dop5 function NO 4 (in MNBOP5)'
  1268.                status = 0
  1269.                RETURN, 0
  1270.             endif
  1271.  
  1272.             ;  Got a minimum between b and c.
  1273.             ;
  1274.             if (fu LT fc) then begin
  1275.                 ax =  DOUBLE( bx )
  1276.                 bx =  DOUBLE( u )
  1277.                 fa =  DOUBLE( fb )
  1278.                 fb =  DOUBLE( fu )
  1279.                 RETURN, 1   ; status should be 1 (ok) here
  1280.  
  1281.             ;  Got a minimum between a and u.
  1282.             ;
  1283.             endif else if (fu GT fb) then begin
  1284.                 cx = DOUBLE( u )
  1285.                 fc = DOUBLE( fu )
  1286.                 RETURN, 1   ; status should be 1 (ok) here
  1287.             endif
  1288.  
  1289.             ;  Parabolic fit was no use, Use default magnification.
  1290.             ;
  1291.             u =  double( cx + gold*(cx - bx) )
  1292.  
  1293.             fu = f1dop5(u, pp, xip, np ,checkF1dim, $
  1294.                 SURFACEINDEX=surfaceindex)
  1295.  
  1296.             ;  Verify the check status of f1dim.
  1297.             ;
  1298.             if (checkF1dim EQ 0) then begin
  1299.                 PRINT, ' error in F1dop5 function NO 5 (in MNBOP5)'
  1300.                 status = 0
  1301.                 RETURN, 0
  1302.             endif
  1303.       
  1304.         ; Parabolic fit is between c and its allowed limit.
  1305.         ;
  1306.         endif else if (((cx - u)*( u - ulim)) GT 0.0) then begin
  1307.  
  1308.             fu = f1dop5(u, pp, xip, np ,checkF1dim, $
  1309.                 SURFACEINDEX=surfaceindex)
  1310.  
  1311.             ;  Verify the check status of f1dim.
  1312.             ;
  1313.             if (checkF1dim EQ 0) then begin
  1314.                 PRINT, ' error in f1dop5 function NO 6 (in MNBOP5)'
  1315.                 status = 0
  1316.                 RETURN, 0
  1317.             endif
  1318.       
  1319.             if (fu LT fc) then begin
  1320.                 arg4 = cx+gold*(cx-bx)
  1321.                 bx = cx
  1322.                 cx = u
  1323.                 u = arg4
  1324.                 fut = f1dop5(u, pp, xip, np , checkF1dim, $
  1325.                     SURFACEINDEX=surfaceindex)
  1326.  
  1327.                 if (checkF1dim EQ 0) then begin
  1328.                     PRINT, ' error in f1dop5 function NO 7 (in MNBOP5)'
  1329.                     status = 0
  1330.                     RETURN, 0
  1331.                 endif
  1332.          
  1333.                 fb = fc
  1334.                 fc = fu
  1335.                 fu = fut
  1336.             endif
  1337.  
  1338.         ;  Limit parabolic u to maximum allowed limit.
  1339.         ;
  1340.         endif else if (( u - ulim)*(ulim - cx) GE 0.0) then begin
  1341.             u = DOUBLE( ulim )
  1342.  
  1343.             fu = f1dop5(u, pp, xip, np , checkF1dim, $
  1344.                 SURFACEINDEX=surfaceindex)
  1345.  
  1346.             ;  Verify the check status of f1dim.
  1347.             ;
  1348.             if (checkF1dim EQ 0) then begin
  1349.                 PRINT, ' error in F1dim function NO 8 (in MNBOP5)'
  1350.                 status = 0
  1351.                 RETURN, 0
  1352.              endif
  1353.  
  1354.         ;  Reject parabolic u, use default magnification.
  1355.         ;
  1356.         endif else begin
  1357.             u =  double( cx + gold*(cx - bx) )
  1358.  
  1359.             fu = f1dop5(u, pp, xip, np , checkF1dim, $
  1360.                 SURFACEINDEX=surfaceindex)
  1361.  
  1362.             ;  Verify the check status of f1dim.
  1363.             ;
  1364.             if (checkF1dim EQ 0) then begin
  1365.                 PRINT, ' error in F1dim function NO 9 (in MNBOP5)'
  1366.                 status = 0
  1367.                 RETURN, 0
  1368.              endif
  1369.         endelse
  1370.  
  1371.         ;  Eliminate oldest point and continue.
  1372.         ;
  1373.         ax = bx
  1374.         bx = cx
  1375.         cx = u
  1376.         fa = fb
  1377.         fb = fc
  1378.         fc = fu
  1379.     endwhile
  1380.  
  1381.     RETURN, status
  1382.  
  1383. end  ; of mnbrak.pro
  1384.       
  1385. pro LINMOP, p, xi, n , fret, status,SurfaceIndex = surfaceindex
  1386. ;
  1387. ; TAKEN from Numerical Recipes in C (2nd ed.).
  1388. ;
  1389. ; This procedure finds the minimum point along the 
  1390. ; direction xi and passing by the point p
  1391. ;
  1392. ; INPUT
  1393. ;      xi             :   inital direction ( dim : n, xi(1) to xi(n)  )
  1394. ;      n              :   The dimension of the surface minus
  1395. ;                          one. Example : the surface z = 3 x + 6y +2.5 
  1396. ;                         (which is a plane) has n = 2 .
  1397. ; surfaceindex :   index that indicates the selected surface (1,2,3)
  1398. ;
  1399. ; INPUT/OUTPUT
  1400. ;      p          :   Initial starting point stored in
  1401. ;                     p(1) to p(n).
  1402. ;                     The returned value is the
  1403. ;                     location of the function minimum along the direction
  1404. ;                     given by xi
  1405. ; OUTPUT
  1406. ;      fret         :   value of the function at point p (minimum)
  1407. ;      status     :   0 = Not valid 
  1408. ;
  1409. ;
  1410. ; THIS PROCEDURE IS CALLED BY
  1411. ;      Procedure POWELM.PRO
  1412. ;
  1413. ; THIS PROCEDURE CALLS  FOR
  1414. ;      Function BRENT.pro
  1415. ;      Function MNBRAK.pro
  1416. ;      Function F1dim.pro ( read this as f one dim. pro)
  1417. ;      Function FUNC.pro 
  1418.  
  1419.  
  1420.     ;  Initialize working variables and arrays.
  1421.     ;
  1422.     tol    = 2.0D-6        ; tolerance passed to BRENT.pro
  1423.     xx     = 1.0D0         ; double precision
  1424.     xmin   = 0.0D0         ; double precision
  1425.     fx     = 0.0D0         ; double precision
  1426.     fb     = 0.0D0         ; double precision
  1427.     fa     = 0.0D0         ; double precision
  1428.     bx     = 0.0D0         ; double precision
  1429.     ax     = 0.0D0         ; double precision
  1430.     status = 1             ; Status is Valid (OK)
  1431.  
  1432.     psaved1 = double(p)
  1433.     psaved2 = double( p )
  1434.     xisaved1 = double( xi )
  1435.     xisaved2 = double( xi )
  1436.     nsaved1 = double( n)
  1437.     nsaved2 = double( n )
  1438.  
  1439.     ;  Call the function MNBRAK.pro .
  1440.     ;  IMPORTANT NOTE : p,xi and n MUST be passed,
  1441.     ;  otherwise an error will be issued.
  1442.     ;
  1443.     checkMnbrak = MNBOP5(ax, xx, bx, fa, fx, fb, $
  1444.         Ppassed = psaved1, Xipassed = xisaved1, Npassed = nsaved1, $
  1445.         SurfaceIndex = surfaceindex) 
  1446.  
  1447.     ;  Verify the check status of MNBRAK.
  1448.     ;
  1449.     if (checkMnbrak EQ 0) then begin
  1450.         print, ' error in MNBRAK NO 1 in LINMIN.pro'
  1451.         status = 0
  1452.         RETURN
  1453.     endif
  1454.  
  1455.     ;  Call the function BRENT.pro.
  1456.     ;  IMPORTANT NOTE : p,xi and n MUST be passed,
  1457.     ;  Otherwise an error will be issued.
  1458.     ;
  1459.     fret = double( BREOP5(ax, xx, bx, tol, xmin, checkBrent, $ 
  1460.         Ppassed = psaved2, Xipassed = xisaved2, Npassed = nsaved2, $
  1461.         SurfaceIndex = surfaceindex) )
  1462.  
  1463.     ;  Verify the check status of  BRENT.PRO.
  1464.     ;
  1465.     if (checkBrent EQ 0) then begin
  1466.         print, ' error in BRENT NO 1 in LINMIN.pro'
  1467.         status = 0
  1468.         RETURN
  1469.     endif
  1470.  
  1471.     ;  Construct the vector results to return.
  1472.     ;
  1473.     xi(1:n) = double( xi(1:n)* xmin )
  1474.     p(1:n) = double( p(1:n) + xi(1:n)) 
  1475.  
  1476. end  ; of LINMIN
  1477.  
  1478.  
  1479.  
  1480. ;---------------------------------------------------------------------------
  1481. ;
  1482. ;  Purpose:   Initialize 16 working (predefined) colors.
  1483. ;
  1484. pro opt_Init16colors, $
  1485.     colornames  ; IN: color anmes array
  1486.  
  1487.     TVLCT, 255, 255, 255, colornames(0)     ; white
  1488.     TVLCT, 255, 255,   0, colornames(1)     ; yellow
  1489.     TVLCT, 200, 180, 255, colornames(2)     ; lavender
  1490.     TVLCT,  80, 255, 255, colornames(3)     ; aqua
  1491.     TVLCT, 255, 100, 150, colornames(4)     ; pink
  1492.     TVLCT,  55, 255,  55, colornames(5)     ; green
  1493.     TVLCT, 255,  30,  30, colornames(6)     ; red
  1494.     TVLCT, 255, 180,  80, colornames(7)     ; orange
  1495.     TVLCT,  80,  80, 255, colornames(8)     ; blue
  1496.     TVLCT, 180, 180, 180, colornames(9)     ; lt_gray
  1497.     TVLCT,  55, 130, 100, colornames(10)    ; med_green
  1498.     TVLCT,  80,  30,  30, colornames(11)    ; brown
  1499.     TVLCT,  55,  55,   0, colornames(12)    ; olive
  1500.     TVLCT, 100,  30,  80, colornames(13)    ; purple
  1501.     TVLCT,  55,  55,  55, colornames(14)    ; dk_gray
  1502.     TVLCT,   0,   0,   0, colornames(15)    ; black
  1503.  
  1504. end  ; of opt_init16colors
  1505.  
  1506. ; -----------------------------------------------------------------------------
  1507. ;
  1508. ;  Purpose:  This procedure initialize the starting points
  1509. ;            (4 points per surface, 3 surfaces, total 12 points).
  1510. ;
  1511. pro opt_InitPoint, $
  1512.     startpoints   ; OUT: start points locations.
  1513.  
  1514.     point = dblarr(2)        ; working array
  1515.     i = 1                    ; surface index
  1516.  
  1517.     point  = [ -1.8d, 2.0d ]
  1518.     startpoints(i,1, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1519.  
  1520.     point  = [ -1.0d, 1.9d ]
  1521.     startpoints(i,2, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1522.  
  1523.     point  = [ 0.0d, 1.9d ]
  1524.     startpoints(i,3, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1525.  
  1526.     point  = [ 1.0d, 2.0d ]
  1527.     startpoints(i,4, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1528.  
  1529.     i = 2
  1530.  
  1531.     point  = [ -1.6d, 1.0d ]
  1532.     startpoints(i,1, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1533.  
  1534.     point  = [ -0.7d, 0.7d ]
  1535.     startpoints(i,2, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1536.  
  1537.     point  = [ 0.75d, -0.875d ]
  1538.     startpoints(i,3, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1539.  
  1540.     point  = [ 1.375d, -1.8d ]
  1541.     startpoints(i,4, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1542.  
  1543.     i = 3
  1544.  
  1545.     point  = [ -0.9d, 0.7d ]
  1546.     startpoints(i,1, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1547.  
  1548.     point  = [ -0.2d, 0.5d ]
  1549.     startpoints(i,2, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1550.  
  1551.     point  = [ 0.2d, -0.2d ]
  1552.     startpoints(i,3, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1553.  
  1554.     point  = [ 0.6d, -0.5d ]
  1555.     startpoints(i,4, 1:3) = [point(0), point(1), FUNCOP(point(0:1),i) ]
  1556.  
  1557. end  ; of INITPOINTS
  1558.  
  1559. ; -----------------------------------------------------------------------------
  1560. ;
  1561. ;  Purpose:  This procedure resets the starting points.
  1562. ;
  1563. pro opt_ResetPoint, $
  1564.     event,  $     ; IN: event structure.
  1565.     pointIndex    ; IN: point index
  1566.  
  1567.     ;  Get the info structure.
  1568.     ;
  1569.     WIDGET_CONTROL, event.top, GET_UVALUE=info, /NO_COPY
  1570.  
  1571.     info.pointindex = pointindex
  1572.  
  1573.     ;  Reset the results labels.
  1574.     ;
  1575.     opt_ResetResult, info.ResultLBLx,info.ResultLBLy, $
  1576.         info.ResultLBLz,info.ResultLBLi
  1577.  
  1578.     if (info.surfaceIndex EQ 1) then begin
  1579.         saved3Dt = info.saved3d1
  1580.         pix = info.pixmap1ID
  1581.     endif else if (info.surfaceIndex EQ 2) then begin
  1582.         saved3Dt = info.saved3d2
  1583.         pix = info.pixmap2ID
  1584.     endif else begin
  1585.         saved3Dt = info.saved3d3
  1586.         pix = info.pixmap3ID
  1587.     endelse
  1588.  
  1589.     ;  Desensitize all the points buttons.
  1590.     ;
  1591.     WIDGET_CONTROL, info.Point1ID, SENSITIVE=0
  1592.     WIDGET_CONTROL, info.Point2ID, SENSITIVE=0
  1593.     WIDGET_CONTROL, info.Point3ID, SENSITIVE=0
  1594.     WIDGET_CONTROL, info.Point4ID, SENSITIVE=0
  1595.  
  1596.     ;  Redraw the surface from the pixmap.
  1597.     ;
  1598.     WSET, info.drawWinID
  1599.     Device, Copy=[ 0,0,info.drawxsize, $
  1600.         info.drawysize, 0,0, pix]
  1601.  
  1602.     ;  Plot all the points.
  1603.     ;
  1604.     opt_PlotPoint, info.surfaceIndex, pointindex, $
  1605.         info.charscale,info.red, $
  1606.         saved3dt, info.startPoints,  $
  1607.         info.startPointsdev, info.fontflag
  1608.  
  1609.     ;  Sensitize the appropriate buttons
  1610.     ; and change the information text label.
  1611.     ;
  1612.     WIDGET_CONTROL, info.startbuttonID, SENSITIVE=1
  1613.     WIDGET_CONTROL, info.surface1ID, SENSITIVE=1
  1614.     WIDGET_CONTROL, info.surface2ID, SENSITIVE=1
  1615.     WIDGET_CONTROL, info.surface3ID, SENSITIVE=1
  1616.     WIDGET_CONTROL, info.StartButtonID, SENSITIVE=1
  1617.     WIDGET_CONTROL, info.FindButton, SENSITIVE=1
  1618.  
  1619.     if (pointindex EQ 1) then begin
  1620.         WIDGET_CONTROL, info.Point1ID, SENSITIVE=0
  1621.         WIDGET_CONTROL, info.Point2ID, SENSITIVE=1
  1622.         WIDGET_CONTROL, info.Point3ID, SENSITIVE=1
  1623.         WIDGET_CONTROL, info.Point4ID, SENSITIVE=1
  1624.     endif else if (pointindex EQ 2) then begin
  1625.         WIDGET_CONTROL, info.Point1ID, SENSITIVE=1
  1626.         WIDGET_CONTROL, info.Point2ID, SENSITIVE=0
  1627.         WIDGET_CONTROL, info.Point3ID, SENSITIVE=1
  1628.         WIDGET_CONTROL, info.Point4ID, SENSITIVE=1
  1629.     endif else if (pointindex EQ 3) then begin
  1630.         WIDGET_CONTROL, info.Point1ID, SENSITIVE=1
  1631.         WIDGET_CONTROL, info.Point2ID, SENSITIVE=1
  1632.         WIDGET_CONTROL, info.Point3ID, SENSITIVE=0
  1633.         WIDGET_CONTROL, info.Point4ID, SENSITIVE=1
  1634.     endif else begin
  1635.         WIDGET_CONTROL, info.Point1ID, SENSITIVE=1
  1636.         WIDGET_CONTROL, info.Point2ID, SENSITIVE=1
  1637.         WIDGET_CONTROL, info.Point3ID, SENSITIVE=1
  1638.         WIDGET_CONTROL, info.Point4ID, SENSITIVE=0
  1639.     endelse
  1640.  
  1641.     ;  Add the annotation string on top of the points.
  1642.     ;
  1643.     opt_ShowStart, info.surfaceIndex, pointindex, $
  1644.         info.StartPoints, info.StartLBL
  1645.  
  1646.     ;  Restore the info structure.
  1647.     ;
  1648.     WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1649.  
  1650. end  ; opt_ResetPoint
  1651.  
  1652. ; -----------------------------------------------------------------------------
  1653. ;
  1654. ;  Purpose:   Redraw the appropriate surface.
  1655. ;
  1656. pro opt_ResetSurface, $
  1657.     event, $       ; IN: event structure
  1658.     surfaceindex   ; IN: surface index (1,2, or 3)
  1659.  
  1660.     ;  Get the info structure.
  1661.     ;
  1662.     WIDGET_CONTROL, event.top, GET_UVALUE=info, /NO_COPY
  1663.  
  1664.     ;  Desensitize all the surface buttons.
  1665.     ;
  1666.     WIDGET_CONTROL, info.surface1ID, sensitive = 0
  1667.     WIDGET_CONTROL, info.surface2ID, sensitive = 0
  1668.     WIDGET_CONTROL, info.surface3ID, sensitive = 0
  1669.  
  1670.     ;  Reset the results labels.
  1671.     ;
  1672.     opt_ResetResult, info.ResultLBLx,info.ResultLBLy, $
  1673.         info.ResultLBLz,info.ResultLBLi
  1674.  
  1675.     info.surfaceIndex = surfaceindex
  1676.     info.pointIndex = 0
  1677.     WSET, info.drawWinID
  1678.  
  1679.     ;  Reset the data system coordinates to the appropriate
  1680.     ;  surface by creating an empty plot....
  1681.     ;
  1682.     if (surfaceindex EQ 1) then begin
  1683.         pix = info.pixmap1ID
  1684.         saved3dt = info.saved3d1
  1685.         SURFACE, info.zdata1, info.xdata1, $
  1686.             info.ydata1,/nodata,  $
  1687.             AZ=10, AX=60, $
  1688.             XSTYLE=4, YSTYLE=4, ZSTYLE=4, $
  1689.             POSITION=[0.1, 0.20, 0.95, 1.]
  1690.     endif else if (surfaceindex EQ 2) then begin
  1691.         pix = info.pixmap2ID
  1692.         saved3dt = info.saved3d2
  1693.         SURFACE, info.zdata2, info.xdata2, $
  1694.             info.ydata2,  /nodata, $
  1695.             AZ=30, AX=30,$
  1696.             XRANGE=[-2,2], $
  1697.             YRANGE=[-2,2], $
  1698.             ZRANGE=[-7,7],$
  1699.             XSTYLE=6, YSTYLE=6, ZSTYLE=6, $
  1700.             POSITION=[0.05, 0.05, 0.95, 1.]
  1701.     endif else begin
  1702.         pix = info.pixmap3ID
  1703.         saved3dt = info.saved3d3
  1704.         SURFACE, info.zdata3, info.xdata3,$
  1705.             info.ydata3, /SAVE,/NODATA, $
  1706.             AZ=30,AX= 30, $
  1707.             XRANGE=[-1,1], $
  1708.             YRANGE=[-1,1], $
  1709.             ZRANGE=[-1,1],$
  1710.             XSTYLE=6, YSTYLE=6, ZSTYLE=6, $
  1711.             POSITION=[0.05, 0.05, 0.95, 1.]
  1712.     endelse
  1713.  
  1714.     ;  Copy the selected surface from 
  1715.     ;  the pixmap into the drawing window.
  1716.     ;
  1717.     DEVICE, COPY=[0, 0, info.drawxsize, $
  1718.         info.drawysize, 0, 0, pix]
  1719.  
  1720.     ;  Plot the starting points.
  1721.     ;
  1722.     opt_PlotPoint, surfaceindex, 1, info.charscale,info.red, $
  1723.         saved3dt, info.startPoints, $
  1724.         info.startPointsdev, info.fontflag,  /ALL
  1725.  
  1726.     ;  Sensitize the appropriate buttons
  1727.     ;  and reset the starting point and information labels.
  1728.     ;
  1729.     WIDGET_CONTROL, info.startbuttonID, SENSITIVE=1
  1730.     WIDGET_CONTROL, info.StartButtonID, SENSITIVE=1
  1731.     WIDGET_CONTROL, info.Point1ID, SENSITIVE=1
  1732.     WIDGET_CONTROL, info.Point2ID, SENSITIVE=1
  1733.     WIDGET_CONTROL, info.Point3ID, SENSITIVE=1
  1734.     WIDGET_CONTROL, info.Point4ID, SENSITIVE=1
  1735.     WIDGET_CONTROL, info.FindButton, SENSITIVE=0
  1736.     WIDGET_CONTROL, info.StartLBL, $
  1737.         Set_Value = 'X = ----   Y = ----'
  1738.  
  1739.     strings = '  Select another surface or a starting point'
  1740.  
  1741.     if (surfaceindex EQ 1) then begin
  1742.         WIDGET_CONTROL, info.surface2ID, SENSITIVE=1
  1743.         WIDGET_CONTROL, info.surface3ID, SENSITIVE=1
  1744.     endif else if( surfaceindex EQ 2) then begin
  1745.         WIDGET_CONTROL, info.surface1ID, SENSITIVE=1
  1746.         WIDGET_CONTROL, info.surface3ID, SENSITIVE=1
  1747.     endif else if( surfaceindex EQ 3) then begin
  1748.         WIDGET_CONTROL, info.surface1ID, SENSITIVE=1
  1749.         WIDGET_CONTROL, info.surface2ID, SENSITIVE=1
  1750.     endif
  1751.  
  1752.     ;  Restore the info structure.
  1753.     ;
  1754.     WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1755.  
  1756. end ; of RESETSURFACE
  1757.  
  1758.  
  1759. ; -----------------------------------------------------------------------------
  1760. ;
  1761. ;  Purpose:   This procedure open a text window and display
  1762. ;             the text file.
  1763. ;
  1764. pro About_Optimization, $
  1765.     group_leader    ;  IN: group leader identifer
  1766.  
  1767.     ;  Return if the info window has already been opened
  1768.     ;
  1769.     if (Xregistered('XDisplayFile') NE 0)  then return
  1770.  
  1771.     XDisplayFile, filepath("optimize.txt", $
  1772.         SUBDIR=['examples','demo','demotext']), $
  1773.         DONE_BUTTON='Done', $
  1774.         TITLE="About Optimization", $
  1775.         GROUP=group_leader, WIDTH=55, HEIGHT=14
  1776.  
  1777. end   ; of About_Optimization
  1778.  
  1779. ; -----------------------------------------------------------------------------
  1780. ;
  1781. ;  Purpose:   Reset the result labels.
  1782. ;
  1783. pro opt_ResetResult, $
  1784.     LabeLxID, $    ; IN: x label
  1785.     LabeLyID, $    ; IN: y label
  1786.     LabeLzID, $    ; IN: z label
  1787.     LabeLiID       ; IN: iteration label
  1788.  
  1789.     ; Reset the result labels
  1790.     ;
  1791.     WIDGET_CONTROL, LabeLxID, $
  1792.         SET_VALUE= 'X =        -----    -----'
  1793.     WIDGET_CONTROL, LabeLyID, $
  1794.         SET_VALUE= 'Y =        -----    -----'
  1795.     WIDGET_CONTROL, LabeLzID, $
  1796.         SET_VALUE= 'Z =        -----    -----'
  1797.     WIDGET_CONTROL, LabeLiID, $
  1798.         SET_VALUE= '#STEPS =   --       --'
  1799.  
  1800. end  ; of opt_ResetResult
  1801.  
  1802. ; -----------------------------------------------------------------------------
  1803. ;
  1804. ;  Purpose: Shows the value of the selected starting point in
  1805. ;           the starting point label.
  1806. ;
  1807. PRO opt_ShowStart, $
  1808.     surfaceIndex, $   ; IN: surface index 
  1809.     pointIndex, $     ; IN: point index
  1810.     startPoints, $    ; IN: starting points array
  1811.     StartLBL          ; IN: start label identifier
  1812.  
  1813.     ;  Shows the value of the selected starting point in
  1814.     ;  the starting point label.
  1815.     ;
  1816.     xval = StartPoints(surfaceIndex, pointIndex, 1)
  1817.     yval = StartPoints(surfaceIndex, pointIndex, 2)
  1818.     xs = STRING(xval, FORMAT='(f6.1)')
  1819.     xs = STRTRIM(xs,2)
  1820.     ys = STRING(yval, FORMAT='(f6.1)')
  1821.     ys = STRTRIM(ys,2)
  1822.     stringh ='X = ' + xs +'   Y = ' + ys
  1823.     WIDGET_CONTROL, StartLBL, SET_VALUE=stringh
  1824.  
  1825. END  ; opt_ShowStart
  1826.  
  1827. ; -----------------------------------------------------------------------------
  1828. ;
  1829. ;  Purpose:  This porcedure plots the starting points
  1830. ;            either the  selected one  or all of them.
  1831. ;
  1832. pro opt_PlotPoint, $
  1833.     surfaceIndex, $     ; IN: surface index
  1834.     pointnumber, $      ; IN: point index
  1835.     charscale, $        ; IN: character scaling factor
  1836.     red, $              ; IN: red color index in color table
  1837.     saved3dIndex, $     ; IN: 3-D transformation matrix
  1838.     startPoints, $      ; IN: start points (data coordinates)
  1839.     startPointsdev, $   ; IN: start points (device coordinates)
  1840.     fontFlag, $         ; IN: font( 0 = hardware, 1 = user selection)
  1841.     All=all             ; IN: (opt) plot all the point
  1842.  
  1843.     !P.T = 0
  1844.     si = surfaceIndex
  1845.  
  1846.     ; If all of the points
  1847.     ;
  1848.     if (N_Elements(all) EQ 1) then begin
  1849.         init =1
  1850.         final = 4
  1851.     endif else begin
  1852.         init = pointNumber
  1853.         final = pointNumber
  1854.     endelse
  1855.  
  1856.  
  1857.     for i = init, final do begin
  1858.         if (i EQ 1) then begin
  1859.             if (fontFlag EQ 0 ) then begin
  1860.                 string ='!51!x'
  1861.             endif else begin
  1862.                 string = '1'
  1863.             endelse
  1864.         endif else if (i EQ 2) then begin
  1865.             if (fontFlag EQ 0 ) then begin
  1866.                 string ='!52!x'
  1867.             endif else begin
  1868.                 string ='2'
  1869.             endelse
  1870.         endif else if (i EQ 3) then begin
  1871.             if (fontFlag EQ 0 ) then begin
  1872.                 string ='!53!x'
  1873.             endif else begin
  1874.                 string ='3'
  1875.             endelse
  1876.         endif else begin
  1877.             if (fontFlag EQ 0 ) then begin
  1878.                 string ='!54!x'
  1879.             endif else begin
  1880.                 string ='4'
  1881.             endelse
  1882.         endelse
  1883.  
  1884.         ;  Plot the point annotations (P1, P2, etc...).
  1885.         ;
  1886.         if (fontFlag EQ 1) then begin
  1887.             !P.FONT = 0
  1888.             DEVICE, FONT="TIMES*24"
  1889.         endif
  1890.  
  1891.         XYOUTS, startPointsdev(si,i,1), startPointsdev(si,i,2)+10, $
  1892.             string, COLOR=red, CHARSIZE=2.*charScale, $
  1893.             /DEVICE, ALIGNMENT=0.5
  1894.  
  1895.         if (fontFlag EQ 1) then begin
  1896.             DEVICE, FONT="TIMES*8"
  1897.             !P.FONT = -1
  1898.         endif
  1899.  
  1900.         ;  Set he 3-D transformation matrix.
  1901.         ;
  1902.         !P.T = saved3dIndex
  1903.  
  1904.         ;  Plot the point symbols.
  1905.         ;
  1906.         PLOTS, $
  1907.             [startPoints(si,i,1), startPoints(si,i,1), $
  1908.                 startPoints(si,i,1)], $
  1909.             [startPoints(si,i,2), startPoints(si,i,2), $
  1910.                 startPoints(si,i,2)], $
  1911.             [startPoints(si,i,3), startPoints(si,i,3), $
  1912.                 startPoints(si,i,3)], $
  1913.             PSYM=1, /Z, COLOR=red, THICK=2.6*charScale, /T3D
  1914.     endfor
  1915.  
  1916.  
  1917.     ;  Reset the 3d transformation.
  1918.     ;
  1919.     !P.T = 0
  1920.  
  1921. end  ; of opt_PlotPoint
  1922.  
  1923. ; -----------------------------------------------------------------------------
  1924. ;
  1925. ;  Purpose:  Main event handler.
  1926. ;
  1927. pro Optimize_event, $
  1928.     event      ; IN: event structure
  1929.  
  1930.     ;  Quit the application using the close box.
  1931.     ;
  1932.     if (TAG_NAMES(event, /STRUCTURE_NAME) EQ $
  1933.         'WIDGET_KILL_REQUEST') then begin
  1934.         WIDGET_CONTROL, event.top, /DESTROY
  1935.         RETURN
  1936.     endif
  1937.  
  1938.  
  1939.     ;  Get the info structure.
  1940.     ;
  1941.     WIDGET_CONTROL, event.top, GET_UVALUE=info, /NO_COPY
  1942.  
  1943.     ;  Get the button identifier value.
  1944.     ;
  1945.     WIDGET_CONTROL, event.id, GET_VALUE=buttonValue
  1946.  
  1947.     ;  Branch to the appropriate button.
  1948.     ;
  1949.     case buttonValue of
  1950.  
  1951.         'Surface 1' :  begin
  1952.             WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1953.             opt_ResetSurface, event, 1
  1954.         end  ; of  Surface 1
  1955.  
  1956.         'Surface 2' :  begin
  1957.             WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1958.             opt_ResetSurface, event, 2
  1959.         end  ; of  Surface 2
  1960.  
  1961.         'Surface 3' :  begin
  1962.             WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1963.             opt_ResetSurface, event, 3
  1964.         end  ; of  Surface 3
  1965.  
  1966.         'Reset Surface' : begin
  1967.             surfaceIndex = info.surfaceIndex
  1968.             WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1969.             opt_ResetSurface, event, surfaceIndex
  1970.         end  ; of  reset surface
  1971.  
  1972.         'Point 1' :  begin
  1973.             WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1974.             opt_ResetPoint, event, 1
  1975.         end  ; of Point 1
  1976.  
  1977.         'Point 2' :  begin
  1978.             WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1979.             opt_ResetPoint, event, 2
  1980.         end  ; of Point 2
  1981.  
  1982.         'Point 3' :  begin
  1983.             WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1984.             opt_ResetPoint, event, 3
  1985.         end  ; of Point 3
  1986.  
  1987.         'Point 4' :  begin
  1988.             WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1989.             opt_ResetPoint, event, 4
  1990.         end  ; of Point 4
  1991.  
  1992.         'Quit' :  begin
  1993.             WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  1994.             WIDGET_CONTROL, event.top, /DESTROY
  1995.         end   ;  of Quit
  1996.  
  1997.         'Find Minimum' : begin
  1998.    
  1999.              ;  Sensitize (desensitize) the appropeiate buttons
  2000.              ;  And reset the information label.
  2001.              ;
  2002.              WIDGET_CONTROL, info.StartButtonID, SENSITIVE=0
  2003.              WIDGET_CONTROL, info.SurfaceButtonID, SENSITIVE=0
  2004.              WIDGET_CONTROL, info.wResetButton, SENSITIVE=0
  2005.              WIDGET_CONTROL, info.findButton, SENSITIVE=0
  2006.              WIDGET_CONTROL, info.QuitButton, SENSITIVE=0
  2007.              WIDGET_CONTROL, info.AboutButtonID, SENSITIVE=0
  2008.  
  2009.              ;  Initialize variable for the DFP function call.
  2010.              ;
  2011.              itmax = 200                 ; Maximum number of iterations
  2012.              gtol = double(1.0D-7)       ; Limit of tolerance
  2013.              xtot = DBLARR(itmax+1,3)    ; Array that contains all the points
  2014.              n = 2                       ; Dimension of the banana function
  2015.              pin = dblarr(3)
  2016.              pin = [0.0, 0.0, 2.5]       ; Initial starting point (p(0) = 0.0)
  2017.              pin(1) = info.startpoints(info.surfaceIndex,$
  2018.                  info.pointIndex,1)
  2019.              pin(2) = info.startpoints(info.surfaceIndex, $
  2020.                  info.pointIndex,2)
  2021.              iter = 0
  2022.  
  2023.              ;  Computes the data points (path).
  2024.              ;
  2025.              DFP, n, pin, gtol, iter, xtot, info.surfaceIndex
  2026.  
  2027.              ;  Put the data path (contained in xtot) within 3 vectors.
  2028.              ;
  2029.              xvec = DBLARR(iter+1)
  2030.              yvec = DBLARR(iter+1)
  2031.              zvec = DBLARR(iter+1)
  2032.              xvec(0:iter) = xtot(0:iter,0)
  2033.              yvec(0:iter) = xtot(0:iter,1)
  2034.              zvec(0:iter) = xtot(0:iter,2)
  2035.  
  2036.              ;  Compute the path with the Powell algorithm.
  2037.              ;
  2038.              ;  Initialize variables for the Powell function call.
  2039.              ;
  2040.              itmax = 200                 ; Maximum number of iterations
  2041.              gtol = double(1.0D-7)       ; Limit of tolerance
  2042.              xtot = DBLARR(itmax+1,3)    ; Array that contains all the points
  2043.              n = 2                       ; Dimension of the banana function
  2044.              pin = dblarr(3)
  2045.              pin = [0.0, 0.0, 2.5]       ; Initial starting point (p(0) = 0.0)
  2046.              pin(0) = 2
  2047.              pin(1) = info.startpoints(info.surfaceIndex,$
  2048.                 info.pointIndex,1)
  2049.              pin(2) = info.startpoints(info.surfaceIndex, $
  2050.                 info.pointIndex,2)
  2051.              ftol = 1.0d-7
  2052.              xi = dblarr(3,3)
  2053.              xi = xi - xi
  2054.              xi(0,0) = 1.0d
  2055.              xi(1,1) = 1.0d
  2056.              xi(2,2) = 1.0d
  2057.  
  2058.              ;  Find the minimum using the POWELL algrithm.
  2059.              ;
  2060.              poweop, pin, xi, ftol, $
  2061.                 iterpo, fretpo,  pathpo, $
  2062.                 statuspo, Surfaceindex = info.surfaceindex
  2063.  
  2064.  
  2065.              ;  Put the data path (contained in pathpo) within 3 vectors.
  2066.              ;
  2067.              xvecpo = DBLARR(iterpo+1)
  2068.              yvecpo = DBLARR(iterpo+1)
  2069.              zvecpo = DBLARR(iterpo+1)
  2070.              xvecpo(0:iterpo) = pathpo(0:iterpo,0)
  2071.              yvecpo(0:iterpo) = pathpo(0:iterpo,1)
  2072.              zvecpo(0:iterpo) = pathpo(0:iterpo,2)
  2073.  
  2074.              ;  Now plotting the DFP only...
  2075.              ;
  2076.              WAIT, 1.0
  2077.              if (info.surfaceIndex EQ 1) then begin
  2078.                  !P.T = info.saved3d1
  2079.              endif else IF( info.surfaceIndex EQ 2) then begin
  2080.                  !P.T = info.saved3d2
  2081.              endif else  begin
  2082.                  !P.T = info.saved3d3
  2083.              endelse
  2084.  
  2085.              ;  Showing the message in the information label.
  2086.              ;
  2087.              string1 = '!3DFP!X'
  2088.              string2 = '!3Powell!X'
  2089.  
  2090.              if (info.fontflag EQ 0) then begin
  2091.                  string1 = '!3DFP!X'
  2092.                  string2 = '!3Powell!X'
  2093.              endif else if (info.fontflag EQ 1) then begin
  2094.                  !p.FONT = 0
  2095.                  Device, FONT = "TIMES*18"
  2096.                  string1 = 'DFP'
  2097.                  string2 = 'Powell'
  2098.              endif
  2099.  
  2100.              XYOUTS, 0.80, 0.1, $
  2101.                  string1, COLOR=info.orange, CHARSIZE=1.0*info.charScale, $
  2102.                  /NORMAL, CHARTHICK=1.0
  2103.  
  2104.              XYOUTS, 0.80, 0.05, $
  2105.                  string2, COLOR=info.white, CHARSIZE=1.0*info.charScale, $
  2106.                  /NORMAL, CHARTHICK=1.0
  2107.  
  2108.  
  2109.              if (info.fontflag EQ 1) then begin
  2110.                  DEVICE, FONT="TIMES*8"
  2111.                  !P.FONT = -1
  2112.              endif
  2113.  
  2114.              ;  Plot the path points, wait 0.3 seconds between each points.
  2115.              ;  Plot the DFP path first.
  2116.              ;
  2117.              for i = 0,iter-1 do begin
  2118.                  PLOTS, [xvec(i),xvec(i+1)], [yvec(i),yvec(i+1)], $
  2119.                      [zvec(i), zvec(i+1)], $
  2120.                      COLOR=info.orange, PSYM=-4, /T3D, $
  2121.                      THICK=2.25,SymSize = 1.6
  2122.                      WAIT, 0.3
  2123.              endfor
  2124.  
  2125.              WAIT, 1.0
  2126.  
  2127.              ;  Plot the POWELL path.
  2128.              ;
  2129.              for i = 0,iterpo-1 do begin
  2130.                  PLOTS, [xvecpo(i),xvecpo(i+1)], [yvecpo(i),yvecpo(i+1)], $
  2131.                      [zvecpo(i), zvecpo(i+1)], $
  2132.                      COLOR=info.white, PSYM=-4, /T3D, $
  2133.                      THICK=2.25,SymSize=1.6
  2134.                  WAIT, 0.3
  2135.              endfor
  2136.  
  2137.              ; Compute the device coordinates of the minimum point.
  2138.              ;
  2139.              mindev = DBLARR(3)
  2140.              mindev = $
  2141.                  CONVERT_COORD(xvec(iter-1), $
  2142.                  yvec(iter-1), $
  2143.                  zvec(iter-1), $
  2144.                  /to_device, /t3D)
  2145.  
  2146.              ;  Annotate the Minimum point.
  2147.              ;
  2148.              string = '!5Min!x'
  2149.              if (info.fontFlag EQ 1) then begin
  2150.                  !P.FONT = 0
  2151.                  DEVICE, FONT="TIMES*24"
  2152.                  string='Min'
  2153.              endif
  2154.              if (info.fontflag EQ 0) then begin
  2155.                  string = '!5Min!x'
  2156.              endif else if (info.fontflag EQ 1) then begin
  2157.                  !p.FONT = 0
  2158.                  DEVICE, FONT = "TIMES*24"
  2159.                  string = 'Min'
  2160.              endif
  2161.              XYOUTS,mindev(0)+ 20,mindev(1) -10,$
  2162.                  string, COLOR=info.red, $
  2163.                  CHARSIZE=2.*info.charScale,/device
  2164.              if (info.fontflag EQ 1) then begin
  2165.                  Device, FONT = "TIMES*8"
  2166.                  !p.FONT = -1
  2167.              endif
  2168.       
  2169.              ;  Draw a circle at the minimum point location.
  2170.              ;
  2171.              XYOUTS, xvec(iter-1), yvec(iter-1), Z=zvec(iter-1), $
  2172.                  '!20P!X', COLOR=info.red, CHARSIZE=2.*info.charScale, $
  2173.                  /T3D, CHARTHICK=2.0
  2174.  
  2175.              ;  Show the results in label box.
  2176.              ;
  2177.              xval = xvec(iter-1)
  2178.              yval = yvec(iter-1)
  2179.              zval = zvec(iter-1)
  2180.  
  2181.              xvalpo = xvecpo(iterpo-1)
  2182.              yvalpo = yvecpo(iterpo-1)
  2183.              zvalpo = zvecpo(iterpo-1)
  2184.  
  2185.              xsdfp = STRING(xval, FORMAT='(f7.4)')
  2186.              xsdfp = STRTRIM(xsdfp,2)
  2187.              ysdfp = STRING(yval, FORMAT='(f7.4)')
  2188.              ysdfp = STRTRIM(ysdfp,2)
  2189.              zsdfp = STRING(zval, FORMAT='(f7.4)')
  2190.              zsdfp = STRTRIM(zsdfp,2)
  2191.              isdfp = STRING(iter, FORMAT='(i3)')
  2192.              isdfp = STRTRIM(isdfp,2)
  2193.  
  2194.              xspow = STRING(xvalpo, FORMAT='(f7.4)')
  2195.              xspow = STRTRIM(xspow,2)
  2196.              yspow = STRING(yvalpo, FORMAT='(f7.4)')
  2197.              yspow = STRTRIM(yspow,2)
  2198.              zspow = STRING(zvalpo, FORMAT='(f7.4)')
  2199.              zspow = STRTRIM(zspow,2)
  2200.              ispow = STRING(iterpo, FORMAT='(i3)')
  2201.              ispow = STRTRIM(ispow,2)
  2202.  
  2203.              space = ' '
  2204.  
  2205.              if (xval   GE 0.0) then sp1 = space else sp1 =''
  2206.              if (xvalpo GE 0.0) then sp2 = space else sp2 =''
  2207.              stringx = 'X =     ' + sp1 + xsdfp + '    ' + sp2 + xspow
  2208.              if (yval   GE 0.0) then sp1 = space else sp1 =''
  2209.              if (yvalpo GE 0.0) then sp2 = space else sp2 =''
  2210.              stringy = 'Y =     ' + sp1 + ysdfp + '    ' + sp2 + yspow
  2211.              if (zval   GE 0.0) then sp1 = space else sp1 =''
  2212.              if (zvalpo GE 0.0) then sp2 = space else sp2 =''
  2213.              stringz = 'Z =     ' + sp1 + zsdfp + '    ' + sp2 + zspow
  2214.              stringi ='#STEPS = ' + isdfp + '            ' +ispow
  2215.  
  2216.  
  2217.              WIDGET_CONTROL, info.ResultLBLx, SET_VALUE=stringx
  2218.              WIDGET_CONTROL, info.ResultLBLy, SET_VALUE=stringy
  2219.              WIDGET_CONTROL, info.ResultLBLz, SET_VALUE=stringz
  2220.              WIDGET_CONTROL, info.ResultLBLi, SET_VALUE=stringi
  2221.  
  2222.              WIDGET_CONTROL, info.SurfaceButtonID, SENSITIVE=1
  2223.              WIDGET_CONTROL, info.StartButtonID, SENSITIVE=1
  2224.              WIDGET_CONTROL, info.findbutton, SENSITIVE=0
  2225.              WIDGET_CONTROL, info.wResetButton, SENSITIVE=1
  2226.              WIDGET_CONTROL, info.QuitButton, SENSITIVE=1
  2227.              WIDGET_CONTROL, info.AboutButtonID, SENSITIVE=1
  2228.  
  2229.              ;  Restore the info structure.
  2230.              ;
  2231.              WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  2232.  
  2233.          end  ; of Find Minimum
  2234.  
  2235.          'About Optimization' :  begin
  2236.  
  2237.              ;  Shows the text file into a window.
  2238.              ;
  2239.              About_Optimization, event.top
  2240.              WIDGET_CONTROL, event.top, SET_UVALUE=info, /NO_COPY
  2241.  
  2242.          end  ; of About optimization
  2243.  
  2244.     endcase   ;  of  buttonValue
  2245.  
  2246. end  ; Optimize_event
  2247.  
  2248. ; -----------------------------------------------------------------------------
  2249. ;
  2250. ;  Purpose:  Cleanup procedure.
  2251. ;
  2252. pro Optimize_Cleanup, $
  2253.     tlb     ;  IN: top level base
  2254.  
  2255.     ;  Get the info structure.
  2256.     ;
  2257.     WIDGET_CONTROL, tlb, GET_UVALUE=info, /no_copy
  2258.  
  2259.     ;  Restore the previous color table.
  2260.     ;
  2261.     TVLCT, info.colorTable
  2262.  
  2263.     ;  Delete the 3 pixmaps.
  2264.     ;
  2265.     WDELETE, info.pixmap1ID
  2266.     WDELETE, info.pixmap2ID
  2267.     WDELETE, info.pixmap3ID
  2268.  
  2269.     if WIDGET_INFO(info.groupBase, /VALID_ID) then $
  2270.         WIDGET_CONTROL, info.groupBase, /MAP
  2271.  
  2272. end  ; Of OPTIMIZE_Cleanup
  2273.  
  2274. ; -----------------------------------------------------------------------------
  2275. ;
  2276. ;  Purpose:  This application shows the minimization (optimization)
  2277. ;            methods by the DFP and POWELL algortihms.
  2278. ;            the user select a starting point and the path
  2279. ;            is displayed.
  2280. ;
  2281. pro D_Optimize, $
  2282.     GROUP=group, $     ; IN: (opt) group identifier
  2283.     APPTLB = appTLB    ; OUT: (opt) TLB of this application
  2284.  
  2285.     ;  This procedure plot the path taken by the
  2286.     ;  DFP and the Powell  minimzation algorithms.
  2287.     ;
  2288.     ;  The user can choose between 3 surfaces and 4 points
  2289.     ;  in each of these surfaces.
  2290.  
  2291.     ;  If there is an error, go back to the user.
  2292.     ;
  2293.     ON_Error, 1
  2294.  
  2295.  
  2296.     ;  Find the number of available colors.
  2297.     ;
  2298.     Window, /FREE, XSIZE = 2, YSIZE=2, /PIXMAP
  2299.     pixid = !D.WINDOW
  2300.     WDELETE, pixid
  2301.     numcolors = !D.TABLE_SIZE
  2302.  
  2303.     ;  If 'OPTIMIZE' is already open, then return...
  2304.     ;
  2305.     if (Xregistered('d_optimize') NE 0) then begin
  2306.       RETURN
  2307.     endif
  2308.  
  2309.     fontFlag = 0     ; 0 = use hersey fonts
  2310.                      ; 1 = use the buitlt in PS fonts (helvetica, etc..)
  2311.  
  2312.     ;  Save the current color table.
  2313.     ;
  2314.     TVLCT, savedR, savedG, savedB, /GET
  2315.     colorTable = [[savedR], [savedG], [savedB]]
  2316.  
  2317.     ; Check the validity of the group identifier.
  2318.     ;
  2319.     ngroup = N_ELEMENTS(group)
  2320.     if (ngroup NE 0) then begin
  2321.         check = WIDGET_INFO(group, /VALID_ID)
  2322.         if (check NE 1) then begin
  2323.             print,'Error, the group identifier is not valid'
  2324.             print, 'Return to the main application'
  2325.             RETURN
  2326.         endif
  2327.         groupBase = group
  2328.     endif else groupBase = 0L
  2329.  
  2330.     begintime = systime(1)
  2331.  
  2332.     ;  Get the screen size.
  2333.     ;
  2334.     DEVICE, GET_SCREEN_SIZE = screenSize
  2335.  
  2336.     ;  Create the starting up message.
  2337.     ;
  2338.     if (ngroup EQ 0) then begin
  2339.         drawbase = startmes()
  2340.     endif else begin
  2341.         drawbase = startmes(GROUP=group)
  2342.     endelse
  2343.  
  2344.     ;  Set up the color table.
  2345.     ;  Here we shift down the color table by 'nshift' positions.
  2346.     ;
  2347.     Window, /FREE, XSIZE=10, YSIZE=10, /PIXMAP
  2348.     pixid = !D.WINDOW
  2349.     WDELETE, pixid
  2350.     max_color = !D.TABLE_SIZE
  2351.  
  2352.     if (max_color GE 2L) then begin
  2353.         white = (max_color - 1L)  > 0L
  2354.         yellow = (max_color - 2L) > 0L
  2355.         lavender = (max_color - 3L) > 0L
  2356.         aqua = (max_color - 4L) > 0L
  2357.         pink = (max_color - 5L) > 0L
  2358.         green = (max_color - 6L) > 0L
  2359.         red = (max_color - 7L) > 0L
  2360.         orange = (max_color - 8L) > 0L
  2361.         blue = (max_color - 9L) > 0L
  2362.         lt_gray = (max_color - 10L) > 0L
  2363.         med_green = (max_color - 11L) > 0L
  2364.         brown = (max_color - 12L) > 0L
  2365.         olive = (max_color - 13L) > 0L
  2366.         purple = (max_color - 14L) > 0L
  2367.         dk_gray = (max_color - 15L) > 0L
  2368.         black = (max_color - 16L) > 0L
  2369.     endif else begin
  2370.         white = 1L
  2371.         yellow = 1L
  2372.         lavender = 1L
  2373.         aqua = 1L
  2374.         pink = 1L
  2375.         green = 1L
  2376.         red = 1L
  2377.         orange = 1L
  2378.         blue = 1L
  2379.         lt_gray = 1L
  2380.         med_green = 0L
  2381.         brown = 0L
  2382.         olive = 0L
  2383.         purple = 0L
  2384.         dk_gray = 0L
  2385.         black = 0L
  2386.     endelse
  2387.  
  2388.     colornames = [white, yellow, lavender, aqua, pink, $
  2389.         green, red, orange, blue, lt_gray, med_green, brown, $
  2390.         olive, purple, dk_gray, black]
  2391.  
  2392.     ;  Number of color indices to shift down.
  2393.     ;
  2394.     bias = FIX( (max_color ) * 0.40)
  2395.     nshift = bias 
  2396.     loadct, 23
  2397.     TVLCT, Rori, Gori, Bori, /GET
  2398.  
  2399.     r = Rori
  2400.     g = Gori
  2401.     b = Bori
  2402.  
  2403.     ncolo = !D.TABLE_SIZE    ; number of available colors
  2404.     r(0:ncolo-nshift-1) = Rori(nshift:ncolo-1)
  2405.     g(0:ncolo-nshift-1) = Gori(nshift:ncolo-1)
  2406.     b(0:ncolo-nshift-1) = Bori(nshift:ncolo-1)
  2407.  
  2408.     for i = 1, nshift do begin
  2409.         r(ncolo-nshift-1+i) = Rori(ncolo-1)
  2410.         g(ncolo-nshift-1+i) = Gori(ncolo-1)
  2411.         b(ncolo-nshift-1+i) = Bori(ncolo-1)
  2412.     endfor
  2413.  
  2414.     ;  Set up the color table.
  2415.     ;
  2416.     TVLCT, r, g, b, 0
  2417.  
  2418.     ;  Assign 16 selected colors at the top of the color table.
  2419.     ;
  2420.     opt_Init16Colors, colornames
  2421.  
  2422.     ;  Get the tips.
  2423.     ;
  2424.     sText = getTips(filepath('optimize.tip', $
  2425.         SUBDIR=['examples','demo', 'demotext']) )
  2426.  
  2427.     ;  This is the character scaling factor for
  2428.     ;  cross-platform compatibility.
  2429.     ;
  2430.     charScale = 8.0/!D.X_CH_SIZE
  2431.  
  2432.     ;  Create the widget heirarchy.
  2433.     ;
  2434.     if (ngroup EQ 0) then begin
  2435.         tlb = WIDGET_BASE(TITLE='Optimization', /COLUMN, $
  2436.             MBAR=bar_base,  $
  2437.             MAP=0, $
  2438.             /TLB_KILL_REQUEST_EVENTS, $
  2439.             TLB_FRAME_ATTR=1)
  2440.     endif else begin
  2441.         tlb = WIDGET_BASE(TITLE='Optimization', /COLUMN, $
  2442.             GROUP_LEADER=group, $
  2443.             MBAR=bar_base,  $
  2444.             MAP=0, $
  2445.             /TLB_KILL_REQUEST_EVENTS, $
  2446.             TLB_FRAME_ATTR=1)
  2447.     endelse
  2448.  
  2449.         ; Create the File|Quit buttons.
  2450.         ;
  2451.         file_menu = WIDGET_BUTTON(bar_base, VALUE='File', /MENU)
  2452.  
  2453.             quit_button = WIDGET_BUTTON(file_menu, VALUE='Quit')
  2454.  
  2455.         ; Create the Help|About buttons.
  2456.         ;
  2457.         help_menu = WIDGET_BUTTON(bar_base, VALUE='About', /HELP, /MENU)
  2458.  
  2459.             about_button = WIDGET_BUTTON(help_menu, $
  2460.                 VALUE='About Optimization')
  2461.  
  2462.  
  2463.         ;  Create the 1st base child of tlb.
  2464.         ;
  2465.         first_base = WIDGET_BASE(tlb, Column = 2)
  2466.  
  2467.             ;  Create sub base of  second base.
  2468.             ;
  2469.             subbase1 = WIDGET_BASE(first_base, Column=1)
  2470.  
  2471.                 ;  Create the selection base (surface and start).
  2472.                 ;
  2473.                 select_base = WIDGET_BASE(subbase1, /COLUMN, $
  2474.                     /BASE_ALIGN_CENTER)
  2475.  
  2476.                     ;  Create the surface pull-down menu
  2477.                     ;
  2478.                     surfaceButtonID = WIDGET_BUTTON(select_base, $
  2479.                         VALUE=' Select a Surface', Menu = 1)
  2480.  
  2481.                         surface1ID = Widget_Button(surfaceButtonID, $
  2482.                             VALUE='Surface 1')
  2483.  
  2484.                         surface2ID = Widget_Button(surfaceButtonID, $
  2485.                             VALUE='Surface 2')
  2486.  
  2487.                         surface3ID = Widget_Button(surfaceButtonID, $
  2488.                             VALUE='Surface 3')
  2489.  
  2490.                     ;  Create the staritng points pull-down menu.
  2491.                     ;
  2492.                     startButtonID = WIDGET_BUTTON(select_base, $
  2493.                         VALUE=' Select a Starting Point', Menu = 1)
  2494.  
  2495.                         point1ID = WIDGET_BUTTON(startButtonID, $
  2496.                             VALUE='Point 1')
  2497.  
  2498.                         point2ID = WIDGET_BUTTON(startButtonID, $
  2499.                             VALUE='Point 2')
  2500.  
  2501.                         point3ID = WIDGET_BUTTON(startButtonID, $
  2502.                             VALUE='Point 3')
  2503.  
  2504.                         point4ID = WIDGET_BUTTON(startButtonID, $
  2505.                             VALUE='Point 4')
  2506.  
  2507.                     ;  Create the button that activates the selections.
  2508.                     ;
  2509.                     find_button = WIDGET_BUTTON(select_base, $
  2510.                         VALUE='Find Minimum')
  2511.  
  2512.                     wResetbutton = WIDGET_BUTTON(select_base, $
  2513.                         VALUE='Reset Surface')
  2514.  
  2515.                 ;  Create a 2nd base child of subbase1
  2516.                 ;  that shows the coordinate of
  2517.                 ;  the selected starting point.
  2518.                 ;
  2519.                 show_Start_base = WIDGET_BASE(subbase1,  $
  2520.                     /COLUMN, /ALIGN_CENTER, YPAD=10)
  2521.  
  2522.                     show_start_label = WIDGET_LABEL(show_start_base, $
  2523.                         VALUE='Starting Point')
  2524.  
  2525.                     show_start_xy = WIDGET_LABEL(show_start_base, $
  2526.                         VALUE='X = -1.2    Y = 2.0')
  2527.  
  2528.                 ;  Create a 3rd base child of subbase1
  2529.                 ;  that shows the DFP results.
  2530.                 ;
  2531.                 show_RES_base = WIDGET_BASE(subbase1, /COLUMN)
  2532.  
  2533.  
  2534.                     show_RES_label = WIDGET_LABEL(show_RES_base, $
  2535.                         /ALIGN_LEFT, $
  2536.                         VALUE='Results   DFP       Powell   ')
  2537.  
  2538.                     show_RES_x = WIDGET_LABEL(show_RES_base, $
  2539.                         /ALIGN_LEFT, $
  2540.                         VALUE='X =      -1.000    -1.000    ')
  2541.  
  2542.                     show_RES_y = WIDGET_LABEL(show_RES_base, $
  2543.                         /ALIGN_LEFT, $
  2544.                         VALUE='Y =      -1.000    -1.000    ')
  2545.  
  2546.                     show_RES_z = WIDGET_LABEL(show_RES_base, $
  2547.                         /ALIGN_LEFT, $
  2548.                         VALUE='Z =      -0.000    -0.000    ')
  2549.  
  2550.                     show_RES_i = WIDGET_LABEL(show_RES_base, $
  2551.                         /ALIGN_LEFT, $
  2552.                         VALUE='#ITER =   24          26    ')
  2553.  
  2554.  
  2555.             ;   Create sub base of the first base.
  2556.             ;
  2557.             subbase2 = WIDGET_BASE(first_base)
  2558.  
  2559.                 ;  Create the drawing area.
  2560.                 ;
  2561.                 drawxsize = 0.6*screenSize(0)
  2562.                 drawysize = 0.8*drawxsize
  2563.                 drawID = Widget_DRAW(subbase2, RETAIN=2, $
  2564.                     XSIZE=drawxsize, YSIZE=drawysize)
  2565.  
  2566.         ;  Create tips texts.
  2567.         ;
  2568.         wStatusBase = WIDGET_BASE(tlb, MAP=0, /ROW)
  2569.  
  2570.             nWidgets = 2
  2571.             wText = LONARR(nWidgets)
  2572.             widTips, wStatusBase, sText.text, XSIZE=36, $
  2573.                 YSIZE=3, NWIDGETS=nWidgets, wText
  2574.  
  2575.     ;  All the widgets has been created.
  2576.  
  2577.     ;  Realize the top-level base.
  2578.     ;
  2579.     WIDGET_CONTROL, tlb, /REALIZE
  2580.  
  2581.     ;  Returns the top level base to the APPTLB keyword.
  2582.     ;
  2583.     appTLB = tlb
  2584.  
  2585.     ;  Size the tips widgets.
  2586.     ;
  2587.     sizeTips, tlb, wText, wStatusBase
  2588.  
  2589.     ; Get the drawing window index
  2590.     ;
  2591.     WIDGET_CONTROL, drawID, GET_VALUE=drawWindowID
  2592.  
  2593.     ;  Create the 3 surfaces.
  2594.     ;  Surface index 1 first (banana function
  2595.     ;
  2596.     surfaceIndex = 1
  2597.     dim_array = 33   ; dimension of the array
  2598.     zdata1 = DBLARR(dim_array, dim_array)
  2599.  
  2600.     xdata1 = FINDGEN(dim_array)/8.0 -2.0
  2601.     ydata1 = FINDGEN(dim_array)/8.0 -1.0
  2602.  
  2603.     ; Create the 2-D arrays of the mesh points
  2604.     ;
  2605.     for i = 0, dim_array-1 do begin
  2606.         for j = 0 , dim_array-1 do begin
  2607.             x = [xdata1(i), ydata1(j)]
  2608.             zdata1(i,j) = FUNCOP(x, surfaceIndex)
  2609.         endfor
  2610.     endfor
  2611.  
  2612.     ;  Create the surface 2 and surface 3 data SETS here.
  2613.     ;
  2614.     surfaceindex = 2
  2615.     dim_array = 33
  2616.     zdata2 = DBLARR(dim_array, dim_array)
  2617.     xdata2 = FINDGEN(dim_array)/8.0 -2.0
  2618.     ydata2 = FINDGEN(dim_array)/8.0 -2.0
  2619.  
  2620.     ;  Create the 2-D arrays of the mesh points.
  2621.     ;
  2622.     for i = 0, dim_array-1 do begin
  2623.         for j = 0 , dim_array-1 do begin
  2624.             x = [xdata2(i), ydata2(j)]
  2625.             zdata2(i,j) = FUNCOP(x, surfaceIndex)
  2626.         endfor
  2627.     endfor
  2628.  
  2629.     ; Create the surface 3  data SETS here
  2630.     ;
  2631.     surfaceindex = 3
  2632.  
  2633.     dim_array = 17
  2634.     zdata3 = DBLARR(dim_array, dim_array)
  2635.  
  2636.     xdata3 = FINDGEN(dim_array)/8.0 -1.0
  2637.     ydata3 = FINDGEN(dim_array)/8.0 -1.0
  2638.  
  2639.     ; Create the 2-D arrays of the mesh points
  2640.     ;
  2641.     for i = 0, dim_array-1 do begin
  2642.         for j = 0 , dim_array-1 do begin
  2643.             x = [xdata3(i), ydata3(j)]
  2644.             zdata3(i,j) = FUNCOP(x, surfaceIndex)
  2645.         endfor
  2646.     endfor
  2647.  
  2648.     ;  Draw the default surface (surface 1) on a newly
  2649.     ;  created pixmap.
  2650.     ;
  2651.     WINDOW, /FREE, XSIZE=drawxsize, YSIZE=drawysize, /PIXMAP
  2652.     pixmap1ID = !d.Window
  2653.  
  2654.     WSET, pixmap1ID
  2655.  
  2656.     ;  Plot the surface 1 on the pixmap
  2657.     ;  and save the 3d tranformation
  2658.     ;
  2659.     if (max_color EQ 16) then begin
  2660.         topc = 15
  2661.     endif else if (max_color GE 17) then begin
  2662.         topc = max_color - 16
  2663.     endif else begin
  2664.         topc = 1
  2665.     endelse
  2666.  
  2667.     ;  Draw the shaded surface of the Banana function without axes.
  2668.     ;
  2669.     SHADE_SURF, zdata1, xdata1, ydata1, /SAVE, $
  2670.         SHADES= BYTSCL(zdata1, TOP=topc), $
  2671.         BACKGROUND=black, AZ=10, AX= 60, $
  2672.         XSTYLE=4, YSTYLE=4, ZSTYLE=4, $
  2673.         POSITION=[0.1, 0.20, 0.95, 1.]
  2674.  
  2675.     ; Draw the mesh surface of the Banana function without axes
  2676.     ;
  2677.     SURFACE, zdata1, xdata1, ydata1, /SAVE,/NOERASE, $
  2678.         COLOR = 31,AZ=10, AX = 60, $
  2679.         XSTYLE=4, YSTYLE=4, ZSTYLE=4, $
  2680.         BACKGROUND=black, $
  2681.         POSITION=[0.1, 0.20, 0.95, 1.]
  2682.  
  2683.     saved3d1 = !p.t
  2684.     !P.T = 0
  2685.  
  2686.     ; Now create the pixmap for the 2nd surface
  2687.     ;
  2688.  
  2689.     ; Save the current color table
  2690.     ;
  2691.     TVLCT, savedR2, savedG2, savedB2, /GET
  2692.     colorTable2=[[savedR2], [savedG2], [savedB2]]
  2693.  
  2694.     WINDOW, /FREE, XSIZE=drawxsize, YSIZE=drawysize, /PIXMAP
  2695.     pixmap2ID = !d.Window
  2696.  
  2697.     !p.T = 0
  2698.     WSET, pixmap2ID
  2699.     TVLCT, Rori, Gori, Bori,0
  2700.  
  2701.     SHADE_SURF, zdata2, xdata2, ydata2, /SAVE, $
  2702.         SHADES=BYTSCL(zdata2, TOP=topc-nshift), $
  2703.         BACKGROUND=black, AZ=30, AX=30, $
  2704.         XRANGE=[-2,2], $
  2705.         YRANGE=[-2,2], $
  2706.         ZRANGE=[-7,7],$
  2707.         XSTYLE=6, YSTYLE=6, ZSTYLE=6, $
  2708.         POSITION=[0.05, 0.05, 0.95, 1.]
  2709.  
  2710.     SURFACE, zdata2, xdata2, ydata2, /SAVE,/NOERASE, $
  2711.         BACKGROUND=black, AZ=30, AX=30, $
  2712.         XRANGE=[-2,2], $
  2713.         YRANGE=[-2,2], $
  2714.         ZRANGE=[-7,7],$
  2715.         COLOR=31, $
  2716.         XSTYLE=6, YSTYLE=6, ZSTYLE=6, $
  2717.         POSITION=[0.05, 0.05, 0.95, 1.]
  2718.  
  2719.     saved3d2 = !p.t
  2720.     TVLCT,colortable2
  2721.  
  2722.     ;  Now create the pixmap for the 3rd surface.
  2723.     ;
  2724.     ;  Save the current color table.
  2725.     ;
  2726.     TVLCT, savedR3, savedG3, savedB3,/GET
  2727.     colorTable3=[[savedR3], [savedG3], [savedB3]]
  2728.  
  2729.     WINDOW, /FREE, XSIZE=drawxsize, YSIZE=drawysize, /PIXMAP
  2730.     pixmap3ID = !d.Window
  2731.  
  2732.     !p.T = 0
  2733.     WSET, pixmap3ID
  2734.     TVLCT, Rori, Gori, Bori,0
  2735.     SHADE_SURF, zdata3, xdata3, ydata3, /SAVE, $
  2736.         shades = BYTSCL(zdata3, TOP = topc-nshift), $
  2737.         BACKGROUND=black, AZ=30, AX=30, $
  2738.         XRANGE=[-1,1], $
  2739.         YRANGE=[-1,1], $
  2740.         ZRANGE=[-1,1],$
  2741.         XSTYLE=6, YSTYLE=6, ZSTYLE=6, $
  2742.         POSITION=[0.05, 0.05, 0.95, 1.]
  2743.  
  2744.     SURFACE, zdata3, xdata3, ydata3, /SAVE,/NOERASE, $
  2745.         BACKGROUND=black, AZ=30, AX=30, $
  2746.         XRANGE=[-1,1], $
  2747.         YRANGE=[-1,1], $
  2748.         ZRANGE=[-1,1],$
  2749.         COLOR=31, $
  2750.         XSTYLE=6, YSTYLE=6, ZSTYLE=6, $
  2751.         POSITION=[0.05, 0.05, 0.95, 1.]
  2752.  
  2753.     saved3d3 = !p.t
  2754.  
  2755.     WSET, drawWindowID
  2756.     !P.T = 0
  2757.     TVLCT,colortable3
  2758.  
  2759.     ;  Initialize the  starting points.
  2760.     ;
  2761.     ;  1st index : surface index (1,2,3)
  2762.     ;  2nd index : point index (1,2,3,4)
  2763.     ;  3rd index ; x, y, z data coordinates
  2764.     ;
  2765.     startPoints = DBLARR(4,5,4)
  2766.     startPointsdev = DBLARR(4,5,4)
  2767.     opt_InitPoint, startpoints
  2768.  
  2769.     ;  Convert the surface 1 data into device coordinates.
  2770.     ;
  2771.     !P.T = 0
  2772.     !P.T = saved3d1
  2773.  
  2774.     d = DBLARR(3,1)
  2775.  
  2776.     ;  Here we create an empty surface in order to
  2777.     ;  establish the data system coordinates.
  2778.     ;  Then, we are able to convert the data into device coordinates.
  2779.     ;
  2780.     SURFACE, zdata1, xdata1, ydata1,/nodata,  $
  2781.         COLOR = 31,AZ=10, AX = 60, $
  2782.         XSTYLE=4, YSTYLE=4, ZSTYLE=4, $
  2783.         BACKGROUND=black, $
  2784.         POSITION=[0.1, 0.20, 0.95, 1.]
  2785.  
  2786.     for i = 1, 4 do begin
  2787.         d = CONVERT_COORD(startPoints(1, i, 1), $
  2788.             startPoints(1, i, 2), $
  2789.             startPoints(1, i, 3), $
  2790.             /TO_DEVICE, /T3D)
  2791.         startPointsdev(1, i, 1:3) = d(0:2, 0)
  2792.     endfor
  2793.  
  2794.     ; Convert the surface 2 data into device coordinates
  2795.     ;
  2796.     !P.T = 0
  2797.     !P.T = saved3d2
  2798.  
  2799.     SURFACE, zdata2, xdata2, $
  2800.         ydata2,  /NODATA, $
  2801.         BACKGROUND=black, AZ=30, AX=30,$
  2802.         XRANGE=[-2,2], $
  2803.         YRANGE=[-2,2], $
  2804.         ZRANGE=[-7,7],$
  2805.         XSTYLE=6, YSTYLE=6, ZSTYLE=6, $
  2806.         POSITION=[0.05, 0.05, 0.95, 1.]
  2807.  
  2808.     d = DBLARR(3,1)
  2809.     for i = 1, 4 do begin
  2810.         d = CONVERT_COORD(startPoints(2, i, 1), $
  2811.             startPoints(2, i, 2), $
  2812.             startPoints(2, i, 3), $
  2813.             /TO_DEVICE, /T3D)
  2814.         startPointsdev(2, i, 1:3) = d(0:2, 0)
  2815.     endfor
  2816.  
  2817.     ; Convert the surface 3 data into device coordinates
  2818.     ;
  2819.     !P.T = 0
  2820.     !P.T = saved3d3
  2821.  
  2822.     SURFACE, zdata3, xdata3, ydata3, /SAVE,/NODATA, $
  2823.         BACKGROUND=black, AZ=30, AX=30,$
  2824.         XRANGE=[-1,1], $
  2825.         YRANGE=[-1,1], $
  2826.         ZRANGE=[-1,1],$
  2827.         XSTYLE=6, YSTYLE=6, ZSTYLE=6, $
  2828.         POSITION=[0.05, 0.05, 0.95, 1.]
  2829.  
  2830.     d = DBLARR(3,1)
  2831.     for i = 1, 4 do begin
  2832.         d = CONVERT_COORD(startPoints(3, i, 1), $
  2833.             startPoints(3, i, 2), $
  2834.             startPoints(3, i, 3), $
  2835.             /TO_DEVICE, /T3D)
  2836.         startPointsdev(3, i, 1:3) = d(0:2, 0)
  2837.     endfor
  2838.  
  2839.     !P.T = 0
  2840.  
  2841.     ;  Point Flag  0 =  No starting point has been selected
  2842.     ;              1 =  A starting point has been selected
  2843.     ;
  2844.     pointFlag = 0
  2845.  
  2846.     ;  Desensitize the Find minimum button.
  2847.     ;
  2848.     WIDGET_CONTROL, find_button, sensitive = 0
  2849.     WIDGET_CONTROL, surface1ID, sensitive = 0
  2850.  
  2851.     ;  Define the info structure.
  2852.     ;
  2853.     info = { $
  2854.         SurfaceButtonID: surfacebuttonID, $   ; Surface button
  2855.         Surface1ID: surface1ID, $             ; Surfaces 1,2,3 buttons
  2856.         Surface2ID: surface2ID, $
  2857.         Surface3ID: surface3ID, $
  2858.         WResetButton: wResetButton, $         ; Reset surface button
  2859.         SurfaceIndex: 1, $                    ; Default surface is no.1
  2860.         StartButtonID: startbuttonID, $       ; Starting Point buttons
  2861.         AboutButtonID: about_button, $        ; Information on the applet
  2862.         Point1ID: point1ID, $
  2863.         Point2ID: point2ID, $
  2864.         Point3ID: point3ID, $
  2865.         Point4ID: point4ID, $
  2866.         FindButton: find_button, $            ; Find button
  2867.         StartLbL: show_start_xy, $            ; Starting point label
  2868.         ResultLbLx : show_res_x, $            ; Results labels
  2869.         ResultLbLy : show_res_y, $
  2870.         ResultLbLz : show_res_z, $
  2871.         ResultLbLi : show_res_i, $            ; Iterations
  2872.         Quitbutton: quit_button, $            ; Quit button in file menu
  2873.         Pixmap1ID: pixmap1ID, $               ; Pixmaps ID's
  2874.         Pixmap2ID: pixmap2ID, $
  2875.         Pixmap3ID :pixmap3ID, $
  2876.         DrawWinID: drawwindowID, $            ; Drawing window
  2877.         Xdata1: xdata1, $                     ; Surface data sets
  2878.         Ydata1: ydata1, $
  2879.         Zdata1: zdata1, $
  2880.         Xdata2: xdata2, $
  2881.         Ydata2: ydata2, $
  2882.         Zdata2: zdata2, $
  2883.         Xdata3: xdata3, $
  2884.         Ydata3: ydata3, $
  2885.         Zdata3: zdata3, $
  2886.         ColorTable: colortable, $             ; Color table to restore
  2887.         PointIndex: 0, $                      ; Selected point
  2888.         PointFlag: pointFlag, $               ; If point selected(0 = no)
  2889.         StartPoints: startpoints, $           ; Starting points in data coor.
  2890.         StartPointsdev: startpointsdev, $     ; Start. points in device coor.
  2891.         Saved3d1: saved3d1, $                 ; 3-D transformation surface 1
  2892.         Saved3d2: saved3d2, $                 ; 3-D transformation surface 2
  2893.         Saved3d3: saved3d3, $                 ; 3-D transformation surface 3
  2894.         drawxsize: drawxsize, $               ; Drawing window size
  2895.         drawysize: drawysize, $
  2896.         Red: red, $                           ; Colors indices
  2897.         Yellow: yellow, $
  2898.         Lavender: lavender, $
  2899.         Aqua: aqua, $
  2900.         Pink: pink, $
  2901.         White: white, $
  2902.         Green: green, $
  2903.         Orange: orange, $
  2904.         Blue: blue, $
  2905.         Lt_gray: lt_gray, $
  2906.         Med_green: med_green, $
  2907.         Brown: brown, $
  2908.         Olive: olive, $
  2909.         Purple: purple, $
  2910.         Dk_gray: dk_gray, $
  2911.         Black: black, $
  2912.         FontFlag : fontflag, $
  2913.         CharScale: charScale, $                ; Character scaling factor
  2914.         groupBase: groupBase $                 ; Base of Group Leader
  2915.     }
  2916.  
  2917.     ;  Reset the result label to default.
  2918.     ;
  2919.     opt_ResetResult, info.ResultLBLx, info.ResultLBLy, $
  2920.         info.ResultLBLz, info.ResultLBLi
  2921.  
  2922.     ;  Set the info structure.
  2923.     ;
  2924.     WIDGET_CONTROL, tlb, SET_UVALUE=info, /NO_COPY
  2925.  
  2926.  
  2927.     ;  Copy surface 1 into the drawing window.
  2928.     ;
  2929.     WSET, drawWindowID
  2930.     SURFACE, zdata1, xdata1, ydata1, /NODATA,  $
  2931.         COLOR=31, AZ=10, AX=60, $
  2932.         XStyle=4, YStyle=4, ZStyle=4, $
  2933.         POSITION=[0.1, 0.20, 0.95, 1.],background = black
  2934.  
  2935.     Device, Copy=[0, 0, drawxsize, drawysize, 0, 0, pixmap1ID]
  2936.  
  2937.     ;  Plot the 4 starting points into the drawing window.
  2938.     ;
  2939.     surfaceIndex = 1
  2940.     pointnumber = 1
  2941.     saved3dt = saved3d1
  2942.     opt_PlotPoint, surfaceIndex, pointnumber, charscale,red, $
  2943.         saved3dt, startPoints, startPointsdev, FontFlag,  /all
  2944.  
  2945.  
  2946.     ;  Destroy the starting up window.
  2947.     ;
  2948.     WIDGET_CONTROL, drawbase, /DESTROY
  2949.  
  2950.     ;  Map the top level base.
  2951.     ;
  2952.     WIDGET_CONTROL, tlb, MAP=1
  2953.  
  2954.     ;  Register with the XManager.
  2955.     ;
  2956.     XMANAGER, "D_OPTIMIZE", tlb, Event_Handler="OPTIMIZE_EVENT",$
  2957.         CLEANUP='OPTIMIZE_CLEANUP', $
  2958.         /NO_BLOCK
  2959.  
  2960. end   ; OF D_OPTIMIZE.PRO
  2961.